172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/*
272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG.
372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License.
772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at
872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and
1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License.
1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.ui;
1972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static android.content.res.Configuration.KEYBOARDHIDDEN_NO;
2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.transaction.ProgressCallbackEntity.PROGRESS_ABORT;
2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.transaction.ProgressCallbackEntity.PROGRESS_COMPLETE;
2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.transaction.ProgressCallbackEntity.PROGRESS_START;
2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.transaction.ProgressCallbackEntity.PROGRESS_STATUS_ACTION;
2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.ui.MessageListAdapter.COLUMN_ID;
266be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylorimport static com.android.mms.ui.MessageListAdapter.COLUMN_MMS_LOCKED;
2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.ui.MessageListAdapter.COLUMN_MSG_TYPE;
2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport static com.android.mms.ui.MessageListAdapter.PROJECTION;
2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.io.File;
31f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.io.FileInputStream;
32f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.io.FileOutputStream;
33f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.io.IOException;
34f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.io.InputStream;
35f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.util.ArrayList;
36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.util.HashMap;
37f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.util.List;
38f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.util.Map;
39f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport java.util.regex.Pattern;
4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.Activity;
4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog;
433b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Mengimport android.content.ActivityNotFoundException;
4472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.AsyncQueryHandler;
4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.BroadcastReceiver;
4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentResolver;
4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.ContentUris;
48440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylorimport android.content.ContentValues;
4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context;
5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface;
5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent;
5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.IntentFilter;
5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface.OnClickListener;
5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Configuration;
5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.res.Resources;
5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.Cursor;
5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.database.sqlite.SQLiteException;
58f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.database.sqlite.SqliteWrapper;
59b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizenimport android.drm.mobile1.DrmException;
60b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizenimport android.drm.mobile1.DrmRawContent;
6172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.drawable.Drawable;
625873d00f37e4a07fad9dd94647fb73ed37f01ae5James Dongimport android.media.CamcorderProfile;
63f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.media.RingtoneManager;
6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri;
6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Bundle;
66ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylorimport android.os.Environment;
6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler;
6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message;
69edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylorimport android.os.Parcelable;
70b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizenimport android.os.SystemProperties;
7160d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylorimport android.provider.ContactsContract;
72b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizenimport android.provider.DrmStore;
7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.MediaStore;
7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.provider.Settings;
756be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylorimport android.provider.ContactsContract.Contacts;
76923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikovimport android.provider.ContactsContract.CommonDataKinds.Email;
779c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylorimport android.provider.MediaStore.Images;
789c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylorimport android.provider.MediaStore.Video;
79f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Mms;
80f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms;
8137321876549776417f035118f157d9531f73de6bWink Savilleimport android.telephony.SmsMessage;
8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.ClipboardManager;
8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Editable;
8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.InputFilter;
8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableString;
8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.Spanned;
8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils;
8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextWatcher;
8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.method.TextKeyListener;
90b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizenimport android.text.style.AbsoluteSizeSpan;
9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.URLSpan;
9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.util.Linkify;
9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Config;
9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log;
9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.ContextMenu;
9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.KeyEvent;
9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.LayoutInflater;
9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.Menu;
9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.MenuItem;
10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View;
10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.ViewStub;
102fc0070e2bd326b9a4290d62dcbf6d8ff29c6ae89Tom Taylorimport android.view.WindowManager;
10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.ContextMenu.ContextMenuInfo;
10472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View.OnCreateContextMenuListener;
10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View.OnKeyListener;
10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.inputmethod.InputMethodManager;
107923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikovimport android.webkit.MimeTypeMap;
10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.AdapterView;
10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Button;
11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.EditText;
11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ImageView;
11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.LinearLayout;
11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ListView;
11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.SimpleAdapter;
11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.TextView;
11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Toast;
11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
118f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.internal.telephony.TelephonyIntents;
119f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.internal.telephony.TelephonyProperties;
120f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.LogTag;
121f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.MmsConfig;
122f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.R;
123f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.data.Contact;
124f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.data.ContactList;
125f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.data.Conversation;
126f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.data.WorkingMessage;
127f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.data.WorkingMessage.MessageStatusListener;
128f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType;
129f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.EncodedStringValue;
130f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.MmsException;
131f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduBody;
132f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPart;
133f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduPersister;
134f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.SendReq;
135f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.model.SlideModel;
136f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.model.SlideshowModel;
137f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.transaction.MessagingNotification;
138f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.ui.MessageUtils.ResizeImageResultCallback;
139f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.ui.RecipientsEditor.RecipientContextMenuInfo;
140f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.util.SendingProgressTokenManager;
141f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.android.mms.util.SmileyParser;
14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/**
14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This is the main UI for:
14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1. Composing a new message;
14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 2. Viewing/managing message history of a conversation.
14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *
14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This activity can handle following parameters from the intent
14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * by which it's launched.
15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * thread_id long Identify the conversation to be viewed. When creating a
15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project *         new message, this parameter shouldn't be present.
15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * msg_uri Uri The message which should be opened for editing in the editor.
15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * address String The addresses of the recipients in current conversation.
15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * exit_on_sent boolean Exit this activity after the message is sent.
15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */
15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class ComposeMessageActivity extends Activity
15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        implements View.OnClickListener, TextView.OnEditorActionListener,
158458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor        MessageStatusListener, Contact.UpdateListener {
15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_ATTACH_IMAGE     = 10;
16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_TAKE_PICTURE     = 11;
16172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_ATTACH_VIDEO     = 12;
16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_TAKE_VIDEO       = 13;
16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_ATTACH_SOUND     = 14;
16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_RECORD_SOUND     = 15;
16572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public static final int REQUEST_CODE_CREATE_SLIDESHOW = 16;
1663b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng    public static final int REQUEST_CODE_ECM_EXIT_DIALOG  = 17;
16760d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor    public static final int REQUEST_CODE_ADD_CONTACT      = 18;
1681d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1699242286c35743422051d439d7460cd0a1426899cWei Huang    private static final String TAG = "Mms/compose";
17008c99d3e1045d9d5dd27d0845e0647d7664bfb4fMark Wagner
17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean DEBUG = false;
17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean TRACE = false;
17372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV;
17472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
17572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Menu ID
17672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_ADD_SUBJECT           = 0;
17772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_DELETE_THREAD         = 1;
17872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_ADD_ATTACHMENT        = 2;
17972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_DISCARD               = 3;
18072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_SEND                  = 4;
18172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_CALL_RECIPIENT        = 5;
18272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_CONVERSATION_LIST     = 6;
18372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Context menu ID
18572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_VIEW_CONTACT          = 12;
18672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_ADD_TO_CONTACTS       = 13;
18772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
18872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_EDIT_MESSAGE          = 14;
18972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_VIEW_SLIDESHOW        = 16;
19072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_VIEW_MESSAGE_DETAILS  = 17;
19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_DELETE_MESSAGE        = 18;
19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_SEARCH                = 19;
19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_DELIVERY_REPORT       = 20;
19472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_FORWARD_MESSAGE       = 21;
19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_CALL_BACK             = 22;
19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_SEND_EMAIL            = 23;
19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_COPY_MESSAGE_TEXT     = 24;
19872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_COPY_TO_SDCARD        = 25;
19972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_INSERT_SMILEY         = 26;
20072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MENU_ADD_ADDRESS_TO_CONTACTS = 27;
201440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor    private static final int MENU_LOCK_MESSAGE          = 28;
202440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor    private static final int MENU_UNLOCK_MESSAGE        = 29;
20307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private static final int MENU_COPY_TO_DRM_PROVIDER  = 30;
20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int RECIPIENTS_MAX_LENGTH = 312;
20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int MESSAGE_LIST_QUERY_TOKEN = 9527;
20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int DELETE_MESSAGE_TOKEN  = 9700;
21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final int CHARS_REMAINING_BEFORE_COUNTER_SHOWN = 10;
21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private static final long NO_DATE_FOR_DIALOG = -1L;
2141d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2153b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng    private static final String EXIT_ECM_RESULT = "exit_ecm_result";
21672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private ContentResolver mContentResolver;
21872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
219ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    private BackgroundQueryHandler mBackgroundQueryHandler;
220ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick
221ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    private Conversation mConversation;     // Conversation we are working in
2221d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
22372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean mExitOnSent;            // Should we finish() after sending a message?
22472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
22572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private View mTopPanel;                 // View containing the recipient and subject editors
22672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private View mBottomPanel;              // View containing the text editor, send button, ec.
22772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private EditText mTextEditor;           // Text editor to type your message into
22872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private TextView mTextCounter;          // Shows the number of characters used in text editor
22972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private Button mSendButton;             // Press to detonate
230b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private EditText mSubjectTextEditor;    // Text editor for MMS subject
23172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
232ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    private AttachmentEditor mAttachmentEditor;
23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
234591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project    private MessageListView mMsgListView;        // ListView for messages in this conversation
235540d263efa2830c154fc32bbad2a7e703cf5747dTom Taylor    public MessageListAdapter mMsgListAdapter;  // and its corresponding ListAdapter
23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private RecipientsEditor mRecipientsEditor;  // UI control for editing recipients
23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean mIsKeyboardOpen;             // Whether the hardware keyboard is visible
24072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean mIsLandscape;                // Whether we're in landscape mode
24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean mPossiblePendingNotification;   // If the message list has changed, we may have
24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                    // a pending notification to deal with.
2441d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
24570262ed72605a86706b3a63810d34adbfd0868a7Wei Huang    private boolean mToastForDraftSave;   // Whether to notify the user that a draft is being saved
24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
247d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang    private boolean mSentMessage;       // true if the user has sent a message while in this
248d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // activity. On a new compose message case, when the first
249d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // message is sent is a MMS w/ attachment, the list blanks
250d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // for a second before showing the sent message. But we'd
251d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // think the message list is empty, thus show the recipients
252d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // editor thinking it's a draft message. This flag should
253d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                                        // help clarify the situation.
254d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang
255b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private WorkingMessage mWorkingMessage;         // The message currently being composed.
2561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
25772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private AlertDialog mSmileyDialog;
2581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
259ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor    private boolean mWaitingForSubActivity;
26007fd438290f18696092b00813ff1c57ac16fa81cTom Taylor    private int mLastRecipientCount;            // Used for warning the user on too many recipients.
2614d620299628c41f9149024f0cf9f42d008aedcf5Tom Taylor    private AttachmentTypeSelectorAdapter mAttachmentTypeSelectorAdapter;
262ca90541d95becdc03a01f51d23c885dc635c0226Mark Wagner
263249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao    private boolean mSendingMessage;    // Indicates the current message is sending, and shouldn't send again.
264249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao
26560d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor    private Intent mAddContactIntent;   // Intent used to add a new contact
26660d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor
267ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    @SuppressWarnings("unused")
2683f5ec94318c06c5e4827a5f7c40205a8335eb758Tom Taylor    private static void log(String logMsg) {
26986bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        Thread current = Thread.currentThread();
27086bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        long tid = current.getId();
27186bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        StackTraceElement[] stack = current.getStackTrace();
27286bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        String methodName = stack[3].getMethodName();
27386bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        // Prepend current thread ID and name of calling method to the message.
2743f5ec94318c06c5e4827a5f7c40205a8335eb758Tom Taylor        logMsg = "[" + tid + "] [" + methodName + "] " + logMsg;
27586bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        Log.d(TAG, logMsg);
27686bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick    }
2771d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
27972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Inner classes
28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
28172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
282b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private void editSlideshow() {
28316f98e62c279550854e665e25c212ea0b04a6b6bTom Taylor        Uri dataUri = mWorkingMessage.saveAsMms(false);
284b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        Intent intent = new Intent(this, SlideshowEditActivity.class);
285b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        intent.setData(dataUri);
286b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        startActivityForResult(intent, REQUEST_CODE_CREATE_SLIDESHOW);
287b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
288b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final Handler mAttachmentEditorHandler = new Handler() {
29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void handleMessage(Message msg) {
29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (msg.what) {
29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_EDIT_SLIDESHOW: {
294b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    editSlideshow();
29572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_SEND_SLIDESHOW: {
29872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (isPreparedForSending()) {
29972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        ComposeMessageActivity.this.confirmSendMessageIfNeeded();
30072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
30172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_VIEW_IMAGE:
3044522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen                case AttachmentEditor.MSG_PLAY_VIDEO:
30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_PLAY_AUDIO:
3064522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen                case AttachmentEditor.MSG_PLAY_SLIDESHOW:
3074522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen                    MessageUtils.viewMmsMessageAttachment(ComposeMessageActivity.this,
308b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                            mWorkingMessage);
30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
31172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_REPLACE_IMAGE:
31272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_REPLACE_VIDEO:
31372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case AttachmentEditor.MSG_REPLACE_AUDIO:
314d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    showAddAttachmentDialog(true);
31572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
31672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
317b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                case AttachmentEditor.MSG_REMOVE_ATTACHMENT:
318edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                    mWorkingMessage.setAttachment(WorkingMessage.TEXT, null, false);
319b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    break;
3201d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
32172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
32272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final Handler mMessageListItemHandler = new Handler() {
32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void handleMessage(Message msg) {
33072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String type;
33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (msg.what) {
33272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MessageListItem.MSG_LIST_EDIT_MMS:
33372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    type = "mms";
33472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
33572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MessageListItem.MSG_LIST_EDIT_SMS:
33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    type = "sms";
33772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    break;
33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
33972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.w(TAG, "Unknown message: " + msg.what);
34072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return;
34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
34332fc80c3da56787085648b83940f897df56b83c4Tom Taylor            MessageItem msgItem = getMessageItem(type, (Long) msg.obj, false);
34472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem != null) {
34572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                editMessageItem(msgItem);
346b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                drawBottomPanel();
34772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
34872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
34972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
35072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final OnKeyListener mSubjectKeyListener = new OnKeyListener() {
35272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public boolean onKey(View v, int keyCode, KeyEvent event) {
35372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (event.getAction() != KeyEvent.ACTION_DOWN) {
35472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return false;
35572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
35672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
35772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // When the subject editor is empty, press "DEL" to hide the input field.
35872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ((keyCode == KeyEvent.KEYCODE_DEL) && (mSubjectTextEditor.length() == 0)) {
359b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                showSubjectEditor(false);
360396a06af4e393f5aab3864c43392a67c60715d38Tom Taylor                mWorkingMessage.setSubject(null, true);
36172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return true;
36272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
36572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
36672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
36832fc80c3da56787085648b83940f897df56b83c4Tom Taylor    /**
36932fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * Return the messageItem associated with the type ("mms" or "sms") and message id.
37032fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * @param type Type of the message: "mms" or "sms"
37132fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * @param msgId Message id of the message. This is the _id of the sms or pdu row and is
37232fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * stored in the MessageItem
37332fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * @param createFromCursorIfNotInCache true if the item is not found in the MessageListAdapter's
37432fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * cache and the code can create a new MessageItem based on the position of the current cursor.
37532fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * If false, the function returns null if the MessageItem isn't in the cache.
37632fc80c3da56787085648b83940f897df56b83c4Tom Taylor     * @return MessageItem or null if not found and createFromCursorIfNotInCache is false
37732fc80c3da56787085648b83940f897df56b83c4Tom Taylor     */
37832fc80c3da56787085648b83940f897df56b83c4Tom Taylor    private MessageItem getMessageItem(String type, long msgId,
37932fc80c3da56787085648b83940f897df56b83c4Tom Taylor            boolean createFromCursorIfNotInCache) {
38032fc80c3da56787085648b83940f897df56b83c4Tom Taylor        return mMsgListAdapter.getCachedMessageItem(type, msgId,
38132fc80c3da56787085648b83940f897df56b83c4Tom Taylor                createFromCursorIfNotInCache ? mMsgListAdapter.getCursor() : null);
38212d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor    }
38312d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor
38412d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor    private boolean isCursorValid() {
38572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Check whether the cursor is valid or not.
3862f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        Cursor cursor = mMsgListAdapter.getCursor();
3872f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        if (cursor.isClosed() || cursor.isBeforeFirst() || cursor.isAfterLast()) {
38872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "Bad cursor.", new RuntimeException());
38912d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor            return false;
39072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
39112d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor        return true;
39272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void resetCounter() {
39572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextCounter.setText("");
39672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextCounter.setVisibility(View.GONE);
39772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
39872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
39972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void updateCounter(CharSequence text, int start, int before, int count) {
400b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        WorkingMessage workingMessage = mWorkingMessage;
401b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        if (workingMessage.requiresMms()) {
4024cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            // If we're not removing text (i.e. no chance of converting back to SMS
4034cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            // because of this change) and we're in MMS mode, just bail out since we
4044cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            // then won't have to calculate the length unnecessarily.
4054cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            final boolean textRemoved = (before > count);
4064cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            if (!textRemoved) {
407b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen                setSendButtonText(workingMessage.requiresMms());
4084cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen                return;
4094cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            }
41072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
4111d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
41272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int[] params = SmsMessage.calculateLength(text, false);
41372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            /* SmsMessage.calculateLength returns an int[4] with:
41472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             *   int[0] being the number of SMS's required,
41572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             *   int[1] the number of code units used,
41672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             *   int[2] is the number of code units remaining until the next message.
41772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             *   int[3] is the encoding type that should be used for the message.
41872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project             */
41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int msgCount = params[0];
42072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int remainingInCurrentMessage = params[2];
42172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
42272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Show the counter only if:
42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // - We are not in MMS mode
42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // - We are going to send more than one message OR we are getting close
42572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean showCounter = false;
426b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        if (!workingMessage.requiresMms() &&
4274cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen                (msgCount > 1 ||
4284cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen                 remainingInCurrentMessage <= CHARS_REMAINING_BEFORE_COUNTER_SHOWN)) {
42972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            showCounter = true;
43072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
4311d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
432b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        setSendButtonText(workingMessage.requiresMms());
433b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen
43472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (showCounter) {
43572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Update the remaining characters and number of messages required.
4364cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            String counterText = msgCount > 1 ? remainingInCurrentMessage + " / " + msgCount
4374cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen                    : String.valueOf(remainingInCurrentMessage);
4384cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            mTextCounter.setText(counterText);
43972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextCounter.setVisibility(View.VISIBLE);
44072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
44172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextCounter.setVisibility(View.GONE);
44272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
44372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
44472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
445ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor    @Override
446ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor    public void startActivityForResult(Intent intent, int requestCode)
447ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor    {
4489de7fc851de8efe7f292a5e4120a4475090950a6Ficus Kirkpatrick        // requestCode >= 0 means the activity in question is a sub-activity.
4499de7fc851de8efe7f292a5e4120a4475090950a6Ficus Kirkpatrick        if (requestCode >= 0) {
4509de7fc851de8efe7f292a5e4120a4475090950a6Ficus Kirkpatrick            mWaitingForSubActivity = true;
4519de7fc851de8efe7f292a5e4120a4475090950a6Ficus Kirkpatrick        }
4521d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
453ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor        super.startActivityForResult(intent, requestCode);
454ece5890ca6c6075ed81324258a4e3991cc45a00fTom Taylor    }
4551d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void toastConvertInfo(boolean toMms) {
457f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        final int resId = toMms ? R.string.converting_to_picture_message
458f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                : R.string.converting_to_text_message;
45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
46072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
4611d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private class DeleteMessageListener implements OnClickListener {
46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        private final Uri mDeleteUri;
4643e10898d774b0005fc776865216651346503024bTom Taylor        private final boolean mDeleteLocked;
46572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4663e10898d774b0005fc776865216651346503024bTom Taylor        public DeleteMessageListener(Uri uri, boolean deleteLocked) {
46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mDeleteUri = uri;
4683e10898d774b0005fc776865216651346503024bTom Taylor            mDeleteLocked = deleteLocked;
46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
47072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
4713e10898d774b0005fc776865216651346503024bTom Taylor        public DeleteMessageListener(long msgId, String type, boolean deleteLocked) {
47272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ("mms".equals(type)) {
473d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang                mDeleteUri = ContentUris.withAppendedId(Mms.CONTENT_URI, msgId);
47472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
475d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang                mDeleteUri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgId);
47672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
4773e10898d774b0005fc776865216651346503024bTom Taylor            mDeleteLocked = deleteLocked;
47872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
47972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onClick(DialogInterface dialog, int whichButton) {
4813e10898d774b0005fc776865216651346503024bTom Taylor            mBackgroundQueryHandler.startDelete(DELETE_MESSAGE_TOKEN,
4823e10898d774b0005fc776865216651346503024bTom Taylor                    null, mDeleteUri, mDeleteLocked ? null : "locked=0", null);
48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
48572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
48672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private class DiscardDraftListener implements OnClickListener {
48772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onClick(DialogInterface dialog, int whichButton) {
488b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mWorkingMessage.discard();
489da51c396e2de55b4bb0cdd953987fed2ffb54a59Tom Taylor            finish();
49072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
49172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private class SendIgnoreInvalidRecipientListener implements OnClickListener {
49472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onClick(DialogInterface dialog, int whichButton) {
4953b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            sendMessage(true);
49672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
49772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
49872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
49972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private class CancelSendingListener implements OnClickListener {
50072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onClick(DialogInterface dialog, int whichButton) {
50172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (isRecipientsEditorVisible()) {
50272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mRecipientsEditor.requestFocus();
50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
50572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void confirmSendMessageIfNeeded() {
5081d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        if (!isRecipientsEditorVisible()) {
5093b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            sendMessage(true);
5101d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            return;
5111d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
5121d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
51378f81825431c8c52cad57bc4a363747533a701abWei Huang        boolean isMms = mWorkingMessage.requiresMms();
51478f81825431c8c52cad57bc4a363747533a701abWei Huang        if (mRecipientsEditor.hasInvalidRecipient(isMms)) {
51578f81825431c8c52cad57bc4a363747533a701abWei Huang            if (mRecipientsEditor.hasValidRecipient(isMms)) {
51672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String title = getResourcesString(R.string.has_invalid_recipient,
51778f81825431c8c52cad57bc4a363747533a701abWei Huang                        mRecipientsEditor.formatInvalidNumbers(isMms));
51872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                new AlertDialog.Builder(this)
51972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
52072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setTitle(title)
52172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setMessage(R.string.invalid_recipient_message)
52272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setPositiveButton(R.string.try_to_send,
52372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            new SendIgnoreInvalidRecipientListener())
52472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setNegativeButton(R.string.no, new CancelSendingListener())
52572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .show();
52672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
52772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                new AlertDialog.Builder(this)
52872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setIcon(android.R.drawable.ic_dialog_alert)
52972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setTitle(R.string.cannot_send_message)
53072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setMessage(R.string.cannot_send_message_reason)
53172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setPositiveButton(R.string.yes, new CancelSendingListener())
53272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .show();
53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
5353b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            sendMessage(true);
53672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final TextWatcher mRecipientsWatcher = new TextWatcher() {
54072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
54172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
54272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
54372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onTextChanged(CharSequence s, int start, int before, int count) {
54472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // This is a workaround for bug 1609057.  Since onUserInteraction() is
54572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // not called when the user touches the soft keyboard, we pretend it was
54672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // called when textfields changes.  This should be removed when the bug
54772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // is fixed.
54872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            onUserInteraction();
54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
55172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void afterTextChanged(Editable s) {
55272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Bug 1474782 describes a situation in which we send to
55372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // the wrong recipient.  We have been unable to reproduce this,
55472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // but the best theory we have so far is that the contents of
55572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // mRecipientList somehow become stale when entering
55672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // ComposeMessageActivity via onNewIntent().  This assertion is
55772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // meant to catch one possible path to that, of a non-visible
55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // mRecipientsEditor having its TextWatcher fire and refreshing
55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // mRecipientList with its stale contents.
56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (!isRecipientsEditorVisible()) {
56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                IllegalStateException e = new IllegalStateException(
56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        "afterTextChanged called with invisible mRecipientsEditor");
56372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Make sure the crash is uploaded to the service so we
56472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // can see if this is happening in the field.
56507cd34eef6ff14e823a3cedfadadeb1c6e535812Tom Taylor                Log.w(TAG,
56607cd34eef6ff14e823a3cedfadadeb1c6e535812Tom Taylor                     "RecipientsWatcher: afterTextChanged called with invisible mRecipientsEditor");
56707cd34eef6ff14e823a3cedfadadeb1c6e535812Tom Taylor                return;
56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
5701d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            mWorkingMessage.setWorkingRecipients(mRecipientsEditor.getNumbers());
571200d37d90dd7640aa909edca6a2b55961faa5824Tom Taylor            mWorkingMessage.setHasEmail(mRecipientsEditor.containsEmail(), true);
5721d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
57307fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            checkForTooManyRecipients();
57407fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
5751d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            // Walk backwards in the text box, skipping spaces.  If the last
5761d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            // character is a comma, update the title bar.
5771d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            for (int pos = s.length() - 1; pos >= 0; pos--) {
5781d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                char c = s.charAt(pos);
5791d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (c == ' ')
5801d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    continue;
5811d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
5821d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (c == ',') {
5838b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                    updateTitle(mConversation.getRecipients());
5841d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                }
5858b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner
5861d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                break;
58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
5881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
589ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            // If we have gone to zero recipients, disable send button.
590ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            updateSendButtonState();
59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
59272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
59407fd438290f18696092b00813ff1c57ac16fa81cTom Taylor    private void checkForTooManyRecipients() {
59507fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        final int recipientLimit = MmsConfig.getRecipientLimit();
59607fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        if (recipientLimit != Integer.MAX_VALUE) {
59707fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            final int recipientCount = recipientCount();
59807fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            boolean tooMany = recipientCount > recipientLimit;
59907fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
60007fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            if (recipientCount != mLastRecipientCount) {
60107fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                // Don't warn the user on every character they type when they're over the limit,
60207fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                // only when the actual # of recipients changes.
60307fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                mLastRecipientCount = recipientCount;
60407fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                if (tooMany) {
60507fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                    String tooManyMsg = getString(R.string.too_many_recipients, recipientCount,
60607fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                            recipientLimit);
60707fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                    Toast.makeText(ComposeMessageActivity.this,
60807fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                            tooManyMsg, Toast.LENGTH_LONG).show();
60907fd438290f18696092b00813ff1c57ac16fa81cTom Taylor                }
61007fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            }
61107fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        }
61207fd438290f18696092b00813ff1c57ac16fa81cTom Taylor    }
61307fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
61472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final OnCreateContextMenuListener mRecipientsMenuCreateListener =
61572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new OnCreateContextMenuListener() {
61672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onCreateContextMenu(ContextMenu menu, View v,
61772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                ContextMenuInfo menuInfo) {
61872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (menuInfo != null) {
6191d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                Contact c = ((RecipientContextMenuInfo) menuInfo).recipient;
6201d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                RecipientsMenuClickListener l = new RecipientsMenuClickListener(c);
62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6221d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                menu.setHeaderTitle(c.getName());
62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6241d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (c.existsInDatabase()) {
62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact)
62672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setOnMenuItemClickListener(l);
6278fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor                } else if (canAddToContacts(c)){
62872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    menu.add(0, MENU_ADD_TO_CONTACTS, 0, R.string.menu_add_to_contacts)
62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setOnMenuItemClickListener(l);
63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
63272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
63372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
63472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final class RecipientsMenuClickListener implements MenuItem.OnMenuItemClickListener {
6361d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        private final Contact mRecipient;
63772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6381d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        RecipientsMenuClickListener(Contact recipient) {
63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mRecipient = recipient;
64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (item.getItemId()) {
64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Context menu handlers for the recipients editor.
64572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_VIEW_CONTACT: {
6461d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    Uri contactUri = mRecipient.getUri();
647dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
648dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
649dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    startActivity(intent);
65072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
65172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_ADD_TO_CONTACTS: {
65360d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    mAddContactIntent = ConversationList.createAddContactIntent(
6541d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                            mRecipient.getNumber());
65560d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    ComposeMessageActivity.this.startActivityForResult(mAddContactIntent,
65660d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                            REQUEST_CODE_ADD_CONTACT);
65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
6648fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor    private boolean canAddToContacts(Contact contact) {
6658fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        // There are some kind of automated messages, like STK messages, that we don't want
6668fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        // to add to contacts. These names begin with special characters, like, "*Info".
667322a547ba74caade04b22158fa8908bcb47add26Satish Roddom        final String name = contact.getName();
6688fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        if (!TextUtils.isEmpty(contact.getNumber())) {
6698fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            char c = contact.getNumber().charAt(0);
6708fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            if (isSpecialChar(c)) {
6718fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor                return false;
6728fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            }
6738fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        }
674322a547ba74caade04b22158fa8908bcb47add26Satish Roddom        if (!TextUtils.isEmpty(name)) {
675322a547ba74caade04b22158fa8908bcb47add26Satish Roddom            char c = name.charAt(0);
6768fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            if (isSpecialChar(c)) {
6778fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor                return false;
6788fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            }
6798fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        }
680ec317d32aec10389fa5832ae8a1164f0375efb2eTom Taylor        if (!(Mms.isEmailAddress(name) || Mms.isPhoneNumber(name) ||
681ec317d32aec10389fa5832ae8a1164f0375efb2eTom Taylor                MessageUtils.isLocalNumber(contact.getNumber()))) {     // Handle "Me"
682322a547ba74caade04b22158fa8908bcb47add26Satish Roddom            return false;
683322a547ba74caade04b22158fa8908bcb47add26Satish Roddom        }
6848fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        return true;
6858fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor    }
68628433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
6878fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor    private boolean isSpecialChar(char c) {
6888fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor        return c == '*' || c == '%' || c == '$';
6898fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor    }
69028433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
69172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void addPositionBasedMenuItems(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
69272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AdapterView.AdapterContextMenuInfo info;
69372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
69472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
69572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            info = (AdapterView.AdapterContextMenuInfo) menuInfo;
69672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (ClassCastException e) {
69772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "bad menuInfo");
69872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
69972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
70072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        final int position = info.position;
70172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        addUriSpecificMenuItems(menu, v, position);
70372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
70472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
70572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private Uri getSelectedUriFromMessageList(ListView listView, int position) {
70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the context menu was opened over a uri, get that uri.
70772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        MessageListItem msglistItem = (MessageListItem) listView.getChildAt(position);
70872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msglistItem == null) {
70972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // FIXME: Should get the correct view. No such interface in ListView currently
71072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // to get the view by position. The ListView.getChildAt(position) cannot
71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // get correct view since the list doesn't create one child for each item.
71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // And if setSelection(position) then getSelectedView(),
71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // cannot get corrent view when in touch mode.
71472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return null;
71572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
71672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
71772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        TextView textView;
71872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        CharSequence text = null;
71972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int selStart = -1;
72072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int selEnd = -1;
72172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
72272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        //check if message sender is selected
72372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        textView = (TextView) msglistItem.findViewById(R.id.text_view);
72472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (textView != null) {
72572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            text = textView.getText();
72672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            selStart = textView.getSelectionStart();
72772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            selEnd = textView.getSelectionEnd();
72872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
72972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
73072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (selStart == -1) {
73172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            //sender is not being selected, it may be within the message body
73272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            textView = (TextView) msglistItem.findViewById(R.id.body_text_view);
73372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (textView != null) {
73472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                text = textView.getText();
73572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                selStart = textView.getSelectionStart();
73672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                selEnd = textView.getSelectionEnd();
73772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
73872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
73972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Check that some text is actually selected, rather than the cursor
74172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // just being placed within the TextView.
74272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (selStart != selEnd) {
74372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int min = Math.min(selStart, selEnd);
74472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int max = Math.max(selStart, selEnd);
74572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            URLSpan[] urls = ((Spanned) text).getSpans(min, max,
74772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                                        URLSpan.class);
74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
74972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (urls.length == 1) {
75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return Uri.parse(urls[0].getURL());
75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
75372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        //no uri was selected
75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return null;
75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
75872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void addUriSpecificMenuItems(ContextMenu menu, View v, int position) {
75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = getSelectedUriFromMessageList((ListView) v, position);
76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (uri != null) {
76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Intent intent = new Intent(null, uri);
76372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            intent.addCategory(Intent.CATEGORY_SELECTED_ALTERNATIVE);
76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.addIntentOptions(0, 0, 0,
76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    new android.content.ComponentName(this, ComposeMessageActivity.class),
76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    null, intent, 0, null);
76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
76872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final void addCallAndContactMenuItems(
77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            ContextMenu menu, MsgListMenuClickListener l, MessageItem msgItem) {
77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Add all possible links in the address & message
77372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        StringBuilder textToSpannify = new StringBuilder();
77472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (msgItem.mBoxId == Mms.MESSAGE_BOX_INBOX) {
77572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            textToSpannify.append(msgItem.mAddress + ": ");
77672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
77772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        textToSpannify.append(msgItem.mBody);
77872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
77972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SpannableString msg = new SpannableString(textToSpannify.toString());
78072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Linkify.addLinks(msg, Linkify.ALL);
78172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ArrayList<String> uris =
78272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            MessageUtils.extractUris(msg.getSpans(0, msg.length(), URLSpan.class));
78372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
78472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        while (uris.size() > 0) {
78572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String uriString = uris.remove(0);
78672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Remove any dupes so they don't get added to the menu multiple times
78772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            while (uris.contains(uriString)) {
78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                uris.remove(uriString);
78972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
7901d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
79172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int sep = uriString.indexOf(":");
79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String prefix = null;
79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (sep >= 0) {
79472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                prefix = uriString.substring(0, sep);
79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                uriString = uriString.substring(sep + 1);
79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            boolean addToContacts = false;
79872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if ("mailto".equalsIgnoreCase(prefix))  {
79972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String sendEmailString = getString(
80072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        R.string.menu_send_email).replace("%s", uriString);
801dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                Intent intent = new Intent(Intent.ACTION_VIEW,
802dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                        Uri.parse("mailto:" + uriString));
803dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
80472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_SEND_EMAIL, 0, sendEmailString)
80572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setOnMenuItemClickListener(l)
806dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    .setIntent(intent);
80772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                addToContacts = !haveEmailContact(uriString);
80872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else if ("tel".equalsIgnoreCase(prefix)) {
80972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String callBackString = getString(
81072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        R.string.menu_call_back).replace("%s", uriString);
811f9ed50ad8005a797230392d79a2cafbf82d026beTom Taylor                Intent intent = new Intent(Intent.ACTION_CALL,
812dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                        Uri.parse("tel:" + uriString));
813dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
81472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_CALL_BACK, 0, callBackString)
81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setOnMenuItemClickListener(l)
816dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    .setIntent(intent);
81772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                addToContacts = !isNumberInContacts(uriString);
81872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
81972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (addToContacts) {
82019be5b3fbe66749f6bc030c9776936b0602ed62fTom Taylor                Intent intent = ConversationList.createAddContactIntent(uriString);
82172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String addContactString = getString(
82272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        R.string.menu_add_address_to_contacts).replace("%s", uriString);
82372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_ADD_ADDRESS_TO_CONTACTS, 0, addContactString)
82472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setOnMenuItemClickListener(l)
82572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setIntent(intent);
82672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
82772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
82872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
82972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
83072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean haveEmailContact(String emailAddress) {
831923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov        Cursor cursor = SqliteWrapper.query(this, getContentResolver(),
832923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov                Uri.withAppendedPath(Email.CONTENT_LOOKUP_URI, Uri.encode(emailAddress)),
833923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov                new String[] { Contacts.DISPLAY_NAME }, null, null, null);
83472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
83572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (cursor != null) {
83672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
83772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                while (cursor.moveToNext()) {
83872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String name = cursor.getString(0);
83972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (!TextUtils.isEmpty(name)) {
84072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return true;
84172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
84272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
84372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } finally {
84472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                cursor.close();
84572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
84672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
84772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
84872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
84972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
85072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isNumberInContacts(String phoneNumber) {
851715e32f97bd9d8ce4b5ba650b97ba4b137150456Tom Taylor        return Contact.get(phoneNumber, false).existsInDatabase();
85272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
85372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
85472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final OnCreateContextMenuListener mMsgListMenuCreateListener =
85572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        new OnCreateContextMenuListener() {
8562f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
8572f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            Cursor cursor = mMsgListAdapter.getCursor();
8582f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            String type = cursor.getString(COLUMN_MSG_TYPE);
8592f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            long msgId = cursor.getLong(COLUMN_ID);
86072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
86172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            addPositionBasedMenuItems(menu, v, menuInfo);
86272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
8632f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            MessageItem msgItem = mMsgListAdapter.getCachedMessageItem(type, msgId, cursor);
86472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem == null) {
86572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Log.e(TAG, "Cannot load message item for type = " + type
86672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        + ", msgId = " + msgId);
86772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return;
86872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
86972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
87072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.setHeaderTitle(R.string.message_options);
87172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
87272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            MsgListMenuClickListener l = new MsgListMenuClickListener();
873331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner
874440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            if (msgItem.mLocked) {
875440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                menu.add(0, MENU_UNLOCK_MESSAGE, 0, R.string.menu_unlock)
876440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    .setOnMenuItemClickListener(l);
877440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            } else {
878440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                menu.add(0, MENU_LOCK_MESSAGE, 0, R.string.menu_lock)
879440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    .setOnMenuItemClickListener(l);
880440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            }
881331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner
88272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem.isMms()) {
88372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                switch (msgItem.mBoxId) {
88472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case Mms.MESSAGE_BOX_INBOX:
88572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
88672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case Mms.MESSAGE_BOX_OUTBOX:
8871d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                        // Since we currently break outgoing messages to multiple
8881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                        // recipients into one message per recipient, only allow
8891d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                        // editing a message for single-recipient conversations.
8901d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                        if (getRecipients().size() == 1) {
89111e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                            menu.add(0, MENU_EDIT_MESSAGE, 0, R.string.menu_edit)
89211e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                                    .setOnMenuItemClickListener(l);
89311e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                        }
89472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
89572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
89672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                switch (msgItem.mAttachmentType) {
897b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    case WorkingMessage.TEXT:
89872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
899b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    case WorkingMessage.VIDEO:
900b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    case WorkingMessage.IMAGE:
90172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (haveSomethingToCopyToSDCard(msgItem.mMsgId)) {
90272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            menu.add(0, MENU_COPY_TO_SDCARD, 0, R.string.copy_to_sdcard)
90372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setOnMenuItemClickListener(l);
90472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
90572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
906b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    case WorkingMessage.SLIDESHOW:
90772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    default:
90872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        menu.add(0, MENU_VIEW_SLIDESHOW, 0, R.string.view_slideshow)
90972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        .setOnMenuItemClickListener(l);
91072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        if (haveSomethingToCopyToSDCard(msgItem.mMsgId)) {
91172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            menu.add(0, MENU_COPY_TO_SDCARD, 0, R.string.copy_to_sdcard)
91272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setOnMenuItemClickListener(l);
91372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        }
91407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                        if (haveSomethingToCopyToDrmProvider(msgItem.mMsgId)) {
91507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                            menu.add(0, MENU_COPY_TO_DRM_PROVIDER, 0,
91607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                                    getDrmMimeMenuStringRsrc(msgItem.mMsgId))
91707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                            .setOnMenuItemClickListener(l);
91807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                        }
91972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
92072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
92172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
92211e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                // Message type is sms. Only allow "edit" if the message has a single recipient
9231d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (getRecipients().size() == 1 &&
92411e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                        (msgItem.mBoxId == Sms.MESSAGE_TYPE_OUTBOX ||
92511e40684ed6c2c2fff5990ff5ccd0a5d775189b9Wei Huang                        msgItem.mBoxId == Sms.MESSAGE_TYPE_FAILED)) {
92672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    menu.add(0, MENU_EDIT_MESSAGE, 0, R.string.menu_edit)
92772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setOnMenuItemClickListener(l);
92872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
92972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
93072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
93172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            addCallAndContactMenuItems(menu, l, msgItem);
93272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
93372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Forward is not available for undownloaded messages.
93472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem.isDownloaded()) {
93572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_FORWARD_MESSAGE, 0, R.string.menu_forward)
93672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        .setOnMenuItemClickListener(l);
93772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
93872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
93972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // It is unclear what would make most sense for copying an MMS message
94072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // to the clipboard, so we currently do SMS only.
94172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem.isSms()) {
94272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_COPY_MESSAGE_TEXT, 0, R.string.copy_message_text)
94372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        .setOnMenuItemClickListener(l);
94472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
94572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
94672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_VIEW_MESSAGE_DETAILS, 0, R.string.view_message_details)
94772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setOnMenuItemClickListener(l);
94872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_DELETE_MESSAGE, 0, R.string.delete_message)
94972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    .setOnMenuItemClickListener(l);
950e7c8092e952d9d5edbc1c0b62e5f872c4d21d2b4Ondrej Novy            if (msgItem.mDeliveryStatus != MessageItem.DeliveryStatus.NONE || msgItem.mReadReport) {
95172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_DELIVERY_REPORT, 0, R.string.view_delivery_report)
95272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        .setOnMenuItemClickListener(l);
95372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
95472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
95572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
95672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
95772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void editMessageItem(MessageItem msgItem) {
95872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ("sms".equals(msgItem.mType)) {
95972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            editSmsMessageItem(msgItem);
96072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
96172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            editMmsMessageItem(msgItem);
96272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
9635a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor        if (msgItem.isFailedMessage() && mMsgListAdapter.getCount() <= 1) {
96472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // For messages with bad addresses, let the user re-edit the recipients.
96572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            initRecipientsEditor();
96672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
96772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
96872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
96972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void editSmsMessageItem(MessageItem msgItem) {
9701c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // When the message being edited is the only message in the conversation, the delete
9711c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // below does something subtle. The trigger "delete_obsolete_threads_pdu" sees that a
9721c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // thread contains no messages and silently deletes the thread. Meanwhile, the mConversation
9731c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // object still holds onto the old thread_id and code thinks there's a backing thread in
9741c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // the DB when it really has been deleted. Here we try and notice that situation and
9751c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // clear out the thread_id. Later on, when Conversation.ensureThreadId() is called, we'll
9761c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        // create a new thread if necessary.
9771c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        synchronized(mConversation) {
9781c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor            if (mConversation.getMessageCount() <= 1) {
9791c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor                mConversation.clearThreadId();
9801c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor            }
9811c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor        }
98272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Delete the old undelivered SMS and load its content.
98372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = ContentUris.withAppendedId(Sms.CONTENT_URI, msgItem.mMsgId);
98472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        SqliteWrapper.delete(ComposeMessageActivity.this,
98572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mContentResolver, uri, null, null);
9861c447686aedf9daf036f5ae7d04de14f0cb2f497Tom Taylor
987b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage.setText(msgItem.mBody);
98872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
98972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
99072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void editMmsMessageItem(MessageItem msgItem) {
991b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // Discard the current message in progress.
992b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage.discard();
9931d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
994b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // Load the selected message in as the working message.
995b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage = WorkingMessage.load(this, msgItem.mMessageUri);
996ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mWorkingMessage.setConversation(mConversation);
9971d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
998b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mAttachmentEditor.update(mWorkingMessage);
999b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        drawTopPanel();
1000f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor
1001755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        // WorkingMessage.load() above only loads the slideshow. Set the
1002755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        // subject here because we already know what it is and avoid doing
1003755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        // another DB lookup in load() just to get it.
1004755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        mWorkingMessage.setSubject(msgItem.mSubject, false);
1005f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor
1006755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        if (mWorkingMessage.hasSubject()) {
1007755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor            showSubjectEditor(true);
1008755cec68c6feddf6c2d2112ba8d580f96fc3e520Tom Taylor        }
100972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
101072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
101172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void copyToClipboard(String str) {
101272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ClipboardManager clip =
101372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
101472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        clip.setText(str);
101572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
101672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1017b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private void forwardMessage(MessageItem msgItem) {
1018f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang        Intent intent = createIntent(this, 0);
1019b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
1020b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        intent.putExtra("exit_on_sent", true);
1021b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        intent.putExtra("forwarded_message", true);
1022f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
1023b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (msgItem.mType.equals("sms")) {
1024b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            intent.putExtra("sms_body", msgItem.mBody);
1025b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        } else {
1026b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            SendReq sendReq = new SendReq();
1027b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            String subject = getString(R.string.forward_prefix);
1028b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            if (msgItem.mSubject != null) {
1029b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                subject += msgItem.mSubject;
1030b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            }
1031b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            sendReq.setSubject(new EncodedStringValue(subject));
1032b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            sendReq.setBody(msgItem.mSlideshow.makeCopy(
1033b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    ComposeMessageActivity.this));
1034b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
1035b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            Uri uri = null;
1036b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            try {
1037b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                PduPersister persister = PduPersister.getPduPersister(this);
1038b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                // Copy the parts of the message here.
1039b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                uri = persister.persist(sendReq, Mms.Draft.CONTENT_URI);
1040b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            } catch (MmsException e) {
1041b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                Log.e(TAG, "Failed to copy message: " + msgItem.mMessageUri, e);
1042b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                Toast.makeText(ComposeMessageActivity.this,
1043b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                        R.string.cannot_save_message, Toast.LENGTH_SHORT).show();
1044b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                return;
1045b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            }
1046b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
1047b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            intent.putExtra("msg_uri", uri);
1048b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            intent.putExtra("subject", subject);
1049b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
105075f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // ForwardMessageActivity is simply an alias in the manifest for ComposeMessageActivity.
105175f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // We have to make an alias because ComposeMessageActivity launch flags specify
105275f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // singleTop. When we forward a message, we want to start a separate ComposeMessageActivity.
105375f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // The only way to do that is to override the singleTop flag, which is impossible to do
105475f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // in code. By creating an alias to the activity, without the singleTop flag, we can
105575f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        // launch a separate ComposeMessageActivity to edit the forward message.
105675f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        intent.setClassName(this, "com.android.mms.ui.ForwardMessageActivity");
105775f79627e52ec0b4ed7ee319945bed9dc34f569fTom Taylor        startActivity(intent);
1058b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
1059b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
106072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
106172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Context menu handlers for the message list view.
106272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
106372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final class MsgListMenuClickListener implements MenuItem.OnMenuItemClickListener {
106472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public boolean onMenuItemClick(MenuItem item) {
106512d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor            if (!isCursorValid()) {
106612d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor                return false;
106712d7e85291b0bd5772e70176e208fce82fd39b8aTom Taylor            }
10682f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            Cursor cursor = mMsgListAdapter.getCursor();
10692f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            String type = cursor.getString(COLUMN_MSG_TYPE);
10702f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            long msgId = cursor.getLong(COLUMN_ID);
107132fc80c3da56787085648b83940f897df56b83c4Tom Taylor            MessageItem msgItem = getMessageItem(type, msgId, true);
107272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
107372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (msgItem == null) {
107472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return false;
107572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
107672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
107772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch (item.getItemId()) {
1078b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                case MENU_EDIT_MESSAGE:
107972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    editMessageItem(msgItem);
1080b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    drawBottomPanel();
108172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
1082b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
1083b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                case MENU_COPY_MESSAGE_TEXT:
108472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    copyToClipboard(msgItem.mBody);
108572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
10861d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1087b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                case MENU_FORWARD_MESSAGE:
1088b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    forwardMessage(msgItem);
108972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
10901d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1091b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                case MENU_VIEW_SLIDESHOW:
10924522cafe21816d43626b8ac42e1c5d3667212a97Ye Wen                    MessageUtils.viewMmsMessageAttachment(ComposeMessageActivity.this,
1093b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                            ContentUris.withAppendedId(Mms.CONTENT_URI, msgId), null);
109472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
1095b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
109672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_VIEW_MESSAGE_DETAILS: {
109772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String messageDetails = MessageUtils.getMessageDetails(
10982f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                            ComposeMessageActivity.this, cursor, msgItem.mMessageSize);
109972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    new AlertDialog.Builder(ComposeMessageActivity.this)
110072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setTitle(R.string.message_details_title)
110172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setMessage(messageDetails)
110272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setPositiveButton(android.R.string.ok, null)
110372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .setCancelable(true)
110472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                            .show();
110572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
110672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
110772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_DELETE_MESSAGE: {
11083e10898d774b0005fc776865216651346503024bTom Taylor                    DeleteMessageListener l = new DeleteMessageListener(
11093e10898d774b0005fc776865216651346503024bTom Taylor                            msgItem.mMessageUri, msgItem.mLocked);
11103e10898d774b0005fc776865216651346503024bTom Taylor                    confirmDeleteDialog(l, msgItem.mLocked);
111172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
111272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
111372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_DELIVERY_REPORT:
111472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    showDeliveryReport(msgId, type);
111572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
111672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
111772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MENU_COPY_TO_SDCARD: {
111872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    int resId = copyMedia(msgId) ? R.string.copy_to_sdcard_success :
111972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        R.string.copy_to_sdcard_fail;
112072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Toast.makeText(ComposeMessageActivity.this, resId, Toast.LENGTH_SHORT).show();
112172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
112272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
1123331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner
112407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                case MENU_COPY_TO_DRM_PROVIDER: {
112507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    int resId = getDrmMimeSavedStringRsrc(msgId, copyToDrmProvider(msgId));
112607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    Toast.makeText(ComposeMessageActivity.this, resId, Toast.LENGTH_SHORT).show();
112707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    return true;
112807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
112907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
1130440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                case MENU_LOCK_MESSAGE: {
1131440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    lockMessage(msgItem, true);
1132440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    return true;
1133440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                }
1134440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor
1135440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                case MENU_UNLOCK_MESSAGE: {
1136440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    lockMessage(msgItem, false);
1137440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                    return true;
1138440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                }
113972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
114072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                default:
114172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return false;
114272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
114372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
114472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
114572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1146440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor    private void lockMessage(MessageItem msgItem, boolean locked) {
1147440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        Uri uri;
1148440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        if ("sms".equals(msgItem.mType)) {
1149440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            uri = Sms.CONTENT_URI;
1150440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        } else {
1151440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            uri = Mms.CONTENT_URI;
1152440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        }
1153b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        final Uri lockUri = ContentUris.withAppendedId(uri, msgItem.mMsgId);
1154440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor
1155440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        final ContentValues values = new ContentValues(1);
1156440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        values.put("locked", locked ? 1 : 0);
1157440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor
1158440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        new Thread(new Runnable() {
1159440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            public void run() {
1160440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                getContentResolver().update(lockUri,
1161440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor                        values, null, null);
1162440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor            }
1163440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor        }).start();
1164440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor    }
1165440071bb40c9c7bac5870a8bb3110edbe665c702Tom Taylor
116672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
116772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Looks to see if there are any valid parts of the attachment that can be copied to a SD card.
116872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * @param msgId
116972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
117072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean haveSomethingToCopyToSDCard(long msgId) {
117107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        PduBody body = PduBodyCache.getPduBody(this,
117207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                ContentUris.withAppendedId(Mms.CONTENT_URI, msgId));
117307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (body == null) {
117472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
117572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
117672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
117772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean result = false;
117872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int partNum = body.getPartsNum();
117972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for(int i = 0; i < partNum; i++) {
118072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            PduPart part = body.getPart(i);
118172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String type = new String(part.getContentType());
118272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1183812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1184293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang                log("[CMA] haveSomethingToCopyToSDCard: part[" + i + "] contentType=" + type);
1185293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang            }
1186293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang
118707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (ContentType.isImageType(type) || ContentType.isVideoType(type) ||
118807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    ContentType.isAudioType(type)) {
118958a68e767b8f859a863976f4094757218f6cdf8bTom Taylor                result = true;
119072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
119172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
119272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
119372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return result;
119472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
119572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
119672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
119707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * Looks to see if there are any drm'd parts of the attachment that can be copied to the
119807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * DrmProvider. Right now we only support saving audio (e.g. ringtones).
119907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * @param msgId
120007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     */
120107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private boolean haveSomethingToCopyToDrmProvider(long msgId) {
120207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        String mimeType = getDrmMimeType(msgId);
120307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return isAudioMimeType(mimeType);
120407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
120507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
120607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    /**
120707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * Simple cache to prevent having to load the same PduBody again and again for the same uri.
120807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     */
120907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private static class PduBodyCache {
121007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        private static PduBody mLastPduBody;
121107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        private static Uri mLastUri;
121207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
121307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        static public PduBody getPduBody(Context context, Uri contentUri) {
121407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (contentUri.equals(mLastUri)) {
121507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                return mLastPduBody;
121607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
121707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            try {
121807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                mLastPduBody = SlideshowModel.getPduBody(context, contentUri);
121907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                mLastUri = contentUri;
122007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor             } catch (MmsException e) {
122107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                 Log.e(TAG, e.getMessage(), e);
122207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                 return null;
122307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor             }
122407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor             return mLastPduBody;
122507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
122607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    };
122707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
122807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    /**
122907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * Copies media from an Mms to the DrmProvider
123007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * @param msgId
123107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     */
123207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private boolean copyToDrmProvider(long msgId) {
123307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        boolean result = true;
123407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        PduBody body = PduBodyCache.getPduBody(this,
123507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                ContentUris.withAppendedId(Mms.CONTENT_URI, msgId));
123607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (body == null) {
123707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            return false;
123807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
123907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
124007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        int partNum = body.getPartsNum();
124107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        for(int i = 0; i < partNum; i++) {
124207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            PduPart part = body.getPart(i);
124307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            String type = new String(part.getContentType());
124407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
124507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (ContentType.isDrmType(type)) {
124607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // All parts (but there's probably only a single one) have to be successful
124707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // for a valid result.
124807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                result &= copyPartToDrmProvider(part);
124907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
125007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
125107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return result;
125207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
125307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
125407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private String mimeTypeOfDrmPart(PduPart part) {
125507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        Uri uri = part.getDataUri();
125607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        InputStream input = null;
125707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        try {
125807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            input = mContentResolver.openInputStream(uri);
125907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (input instanceof FileInputStream) {
126007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                FileInputStream fin = (FileInputStream) input;
126107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
1262923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov                DrmRawContent content = new DrmRawContent(fin, fin.available(),
126307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                        DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING);
126407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                String mimeType = content.getContentType();
126507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                return mimeType;
126607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
126707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        } catch (IOException e) {
126807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            // Ignore
126907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            Log.e(TAG, "IOException caught while opening or reading stream", e);
127007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        } catch (DrmException e) {
127107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            Log.e(TAG, "DrmException caught ", e);
127207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        } finally {
127307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (null != input) {
127407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                try {
127507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    input.close();
127607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                } catch (IOException e) {
127707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    // Ignore
127807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    Log.e(TAG, "IOException caught while closing stream", e);
127907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
128007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
128107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
128207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return null;
128307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
128407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
128507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    /**
128607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * Returns the type of the first drm'd pdu part.
128707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     * @param msgId
128807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor     */
128907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private String getDrmMimeType(long msgId) {
129007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        PduBody body = PduBodyCache.getPduBody(this,
129107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                ContentUris.withAppendedId(Mms.CONTENT_URI, msgId));
129207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (body == null) {
129307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            return null;
129407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
129507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
129607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        int partNum = body.getPartsNum();
129707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        for(int i = 0; i < partNum; i++) {
129807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            PduPart part = body.getPart(i);
129907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            String type = new String(part.getContentType());
130007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
130107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (ContentType.isDrmType(type)) {
130207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                return mimeTypeOfDrmPart(part);
130307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
130407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
130507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return null;
130607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
130707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
130807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private int getDrmMimeMenuStringRsrc(long msgId) {
130907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        String mimeType = getDrmMimeType(msgId);
131007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (isAudioMimeType(mimeType)) {
131107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            return R.string.save_ringtone;
131207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
131307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return 0;
131407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
131507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
131607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private int getDrmMimeSavedStringRsrc(long msgId, boolean success) {
131707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        String mimeType = getDrmMimeType(msgId);
131807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (isAudioMimeType(mimeType)) {
131907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            return success ? R.string.saved_ringtone : R.string.saved_ringtone_fail;
132007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
132107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return 0;
132207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
132307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
132407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private boolean isAudioMimeType(String mimeType) {
132507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return mimeType != null && mimeType.startsWith("audio/");
132607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
132707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
132807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private boolean isImageMimeType(String mimeType) {
132907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return mimeType != null && mimeType.startsWith("image/");
133007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
133107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
133207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    private boolean copyPartToDrmProvider(PduPart part) {
133307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        Uri uri = part.getDataUri();
133407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
133507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        InputStream input = null;
133607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        try {
133707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            input = mContentResolver.openInputStream(uri);
133807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (input instanceof FileInputStream) {
133907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                FileInputStream fin = (FileInputStream) input;
134007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
134107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // Build a nice title
134207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                byte[] location = part.getName();
134307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                if (location == null) {
134407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    location = part.getFilename();
134507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
134607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                if (location == null) {
134707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    location = part.getContentLocation();
134807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
134907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
135007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // Depending on the location, there may be an
135107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // extension already on the name or not
135207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                String title = new String(location);
135307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                int index;
135407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                if ((index = title.indexOf(".")) == -1) {
135507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    String type = new String(part.getContentType());
135607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                } else {
135707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    title = title.substring(0, index);
135807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
135907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
136007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                // transfer the file to the DRM content provider
136107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                Intent item = DrmStore.addDrmFile(mContentResolver, fin, title);
136207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                if (item == null) {
136307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    Log.w(TAG, "unable to add file " + uri + " to DrmProvider");
136407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    return false;
136507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
136607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
136707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        } catch (IOException e) {
136807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            // Ignore
136907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            Log.e(TAG, "IOException caught while opening or reading stream", e);
137007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            return false;
137107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        } finally {
137207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (null != input) {
137307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                try {
137407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    input.close();
137507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                } catch (IOException e) {
137607dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    // Ignore
137707dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    Log.e(TAG, "IOException caught while closing stream", e);
137807dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    return false;
137907dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                }
138007dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            }
138107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        }
138207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        return true;
138307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    }
138407dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor
138507dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor    /**
138672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Copies media from an Mms to the "download" directory on the SD card
138772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * @param msgId
138872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
138972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean copyMedia(long msgId) {
139072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean result = true;
139107dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        PduBody body = PduBodyCache.getPduBody(this,
139207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                ContentUris.withAppendedId(Mms.CONTENT_URI, msgId));
139307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor        if (body == null) {
139472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
139572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
139672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
139772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        int partNum = body.getPartsNum();
139872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for(int i = 0; i < partNum; i++) {
139972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            PduPart part = body.getPart(i);
140072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String type = new String(part.getContentType());
140172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
140207dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor            if (ContentType.isImageType(type) || ContentType.isVideoType(type) ||
140307dde49d355fbe188b1ead3276544c4a324ebd11Tom Taylor                    ContentType.isAudioType(type)) {
1404fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                result &= copyPart(part, Long.toHexString(msgId));   // all parts have to be successful for a valid result.
140572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
140672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
140772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return result;
140872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
140972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1410fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao    private boolean copyPart(PduPart part, String fallback) {
141172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Uri uri = part.getDataUri();
141272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
141372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        InputStream input = null;
141472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        FileOutputStream fout = null;
141572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
141672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            input = mContentResolver.openInputStream(uri);
141772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (input instanceof FileInputStream) {
141872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                FileInputStream fin = (FileInputStream) input;
141972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
142072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                byte[] location = part.getName();
142172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (location == null) {
142272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = part.getFilename();
142372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
142472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (location == null) {
142572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    location = part.getContentLocation();
142672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
142772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1428fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                String fileName;
1429fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                if (location == null) {
1430fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                    // Use fallback name.
1431fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                    fileName = fallback;
1432fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                } else {
1433fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                    fileName = new String(location);
1434fe2332c7ae78ca4d4e1b4ea0f8a948536d16f3d8Bai Tao                }
143572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Depending on the location, there may be an
143672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // extension already on the name or not
1437ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylor                String dir = Environment.getExternalStorageDirectory() + "/"
1438ebea1f24c246b8fa972ab9cbe52e6f506c5fc825Tom Taylor                                + Environment.DIRECTORY_DOWNLOADS  + "/";
143972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                String extension;
144072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                int index;
144172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if ((index = fileName.indexOf(".")) == -1) {
144272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    String type = new String(part.getContentType());
144372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(type);
144472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } else {
144572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    extension = fileName.substring(index + 1, fileName.length());
144672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    fileName = fileName.substring(0, index);
144772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
144872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
144972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                File file = getUniqueDestination(dir + fileName, extension);
145072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
145172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // make sure the path is valid and directories created for this file.
145272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                File parentFile = file.getParentFile();
145372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (!parentFile.exists() && !parentFile.mkdirs()) {
145472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, "[MMS] copyPart: mkdirs for " + parentFile.getPath() + " failed!");
145572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return false;
145672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
145772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
145872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                fout = new FileOutputStream(file);
145972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
146072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                byte[] buffer = new byte[8000];
1461293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang                int size = 0;
1462293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang                while ((size=fin.read(buffer)) != -1) {
1463293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang                    fout.write(buffer, 0, size);
146472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
146572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
146672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Notify other applications listening to scanner events
146772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // that a media file has been added to the sd card
146872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
146972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Uri.fromFile(file)));
147072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
147172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (IOException e) {
147272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Ignore
147372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.e(TAG, "IOException caught while opening or reading stream", e);
147472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
147572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } finally {
147672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null != input) {
147772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
147872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    input.close();
147972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
148072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Ignore
148172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, "IOException caught while closing stream", e);
148272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return false;
148372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
148472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
148572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (null != fout) {
148672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
148772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    fout.close();
148872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } catch (IOException e) {
148972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    // Ignore
149072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Log.e(TAG, "IOException caught while closing stream", e);
149172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return false;
149272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
149372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
149472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
149572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
149672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
149772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
149872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private File getUniqueDestination(String base, String extension) {
149972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        File file = new File(base + "." + extension);
150072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
150172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        for (int i = 2; file.exists(); i++) {
150272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            file = new File(base + "_" + i + "." + extension);
150372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
150472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return file;
150572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
150672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
150772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void showDeliveryReport(long messageId, String type) {
150872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Intent intent = new Intent(this, DeliveryReportActivity.class);
150972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.putExtra("message_id", messageId);
151072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        intent.putExtra("message_type", type);
151172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
151272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        startActivity(intent);
151372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
151472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
151572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final IntentFilter mHttpProgressFilter = new IntentFilter(PROGRESS_STATUS_ACTION);
151672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
151772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final BroadcastReceiver mHttpProgressReceiver = new BroadcastReceiver() {
151872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
151972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onReceive(Context context, Intent intent) {
152072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (PROGRESS_STATUS_ACTION.equals(intent.getAction())) {
152172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                long token = intent.getLongExtra("token",
152272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                    SendingProgressTokenManager.NO_TOKEN);
1523ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick                if (token != mConversation.getThreadId()) {
152472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return;
152572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
152672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
152772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                int progress = intent.getIntExtra("progress", 0);
152872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                switch (progress) {
152972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case PROGRESS_START:
153072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        setProgressBarVisibility(true);
153172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
153272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case PROGRESS_ABORT:
153372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    case PROGRESS_COMPLETE:
153472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        setProgressBarVisibility(false);
153572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
153672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    default:
153772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        setProgress(100 * progress);
153872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
153972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
154072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
154172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
154272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
15431d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    private static ContactList sEmptyContactList;
15441d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
15451d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    private ContactList getRecipients() {
15461d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // If the recipients editor is visible, the conversation has
15471d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // not really officially 'started' yet.  Recipients will be set
15481d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // on the conversation once it has been saved or sent.  In the
15491d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // meantime, let anyone who needs the recipient list think it
15501d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // is empty rather than giving them a stale one.
15511d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        if (isRecipientsEditorVisible()) {
15521d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            if (sEmptyContactList == null) {
15531d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                sEmptyContactList = new ContactList();
15541d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
15551d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            return sEmptyContactList;
15561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
15571d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        return mConversation.getRecipients();
15581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick    }
15591d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
15608b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner    private void updateTitle(ContactList list) {
15618b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        String s;
15620be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner        switch (list.size()) {
15638b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            case 0: {
15644c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang                String recipient = "";
15654c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang                if (mRecipientsEditor != null) {
15664c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang                    recipient = mRecipientsEditor.getText().toString();
15674c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang                }
15688b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                s = recipient;
15690be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner                break;
15708b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            }
15718b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            case 1: {
15728b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                s = list.get(0).getNameAndNumber();
15730be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner                break;
15748b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            }
15758b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            default: {
157677864ad24e1a12709c7e226546b24badc22806bdTom Taylor                // Handle multiple recipients
15778b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                s = list.formatNames(", ");
15780be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner                break;
15798b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            }
15800be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner        }
15818b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        getWindow().setTitle(s);
15820be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner    }
15830be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner
158472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Get the recipients editor ready to be displayed onscreen.
158572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void initRecipientsEditor() {
15863d2107af884e95720b72201e99d9ab4bce9bba3bTom Taylor        if (isRecipientsEditorVisible()) {
15873d2107af884e95720b72201e99d9ab4bce9bba3bTom Taylor            return;
15883d2107af884e95720b72201e99d9ab4bce9bba3bTom Taylor        }
1589e24e5684d04e7f6337bc90377422f84fcf2b1f0dTom Taylor        // Must grab the recipients before the view is made visible because getRecipients()
1590e24e5684d04e7f6337bc90377422f84fcf2b1f0dTom Taylor        // returns empty recipients when the editor is visible.
1591e24e5684d04e7f6337bc90377422f84fcf2b1f0dTom Taylor        ContactList recipients = getRecipients();
159228433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
159372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ViewStub stub = (ViewStub)findViewById(R.id.recipients_editor_stub);
159472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (stub != null) {
159572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mRecipientsEditor = (RecipientsEditor) stub.inflate();
159672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
159772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mRecipientsEditor = (RecipientsEditor)findViewById(R.id.recipients_editor);
159872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mRecipientsEditor.setVisibility(View.VISIBLE);
159972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
160072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
160172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mRecipientsEditor.setAdapter(new RecipientsAdapter(this));
1602e24e5684d04e7f6337bc90377422f84fcf2b1f0dTom Taylor        mRecipientsEditor.populate(recipients);
160372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mRecipientsEditor.setOnCreateContextMenuListener(mRecipientsMenuCreateListener);
160472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mRecipientsEditor.addTextChangedListener(mRecipientsWatcher);
160572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mRecipientsEditor.setFilters(new InputFilter[] {
160672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                new InputFilter.LengthFilter(RECIPIENTS_MAX_LENGTH) });
160772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mRecipientsEditor.setOnItemClickListener(new AdapterView.OnItemClickListener() {
160872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
160972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // After the user selects an item in the pop-up contacts list, move the
161072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // focus to the text editor if there is only one recipient.  This helps
161172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // the common case of selecting one recipient and then typing a message,
161272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // but avoids annoying a user who is trying to add five recipients and
161372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // keeps having focus stolen away.
16141d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (mRecipientsEditor.getRecipientCount() == 1) {
161500a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                    // if we're in extract mode then don't request focus
161600a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                    final InputMethodManager inputManager = (InputMethodManager)
161700a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                        getSystemService(Context.INPUT_METHOD_SERVICE);
161800a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                    if (inputManager == null || !inputManager.isFullscreenMode()) {
161900a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                        mTextEditor.requestFocus();
162000a6a244e1743be468bd3ab709781ef9751aa8c2Mark Wagner                    }
162172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
162272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
162372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        });
162472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16250be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner        mRecipientsEditor.setOnFocusChangeListener(new View.OnFocusChangeListener() {
16260be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner            public void onFocusChange(View v, boolean hasFocus) {
16270be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner                if (!hasFocus) {
16282c8a398f5562569d46215dec1455c1dc04b3ba1aMark Wagner                    RecipientsEditor editor = (RecipientsEditor) v;
1629cab73c66f1b07a639cbb75b6510d425477cbcaecTom Taylor                    ContactList contacts = editor.constructContactsFromInput();
16308b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                    updateTitle(contacts);
16310be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner                }
16320be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner            }
16330be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner        });
16340be5770b07cbd03eea9cd821ef02c8480020b162Mark Wagner
163572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTopPanel.setVisibility(View.VISIBLE);
163672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
163772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
163872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
163972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Activity methods
164072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
164172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
164295817b166d415114bac89ca0946c3717ae229526Tom Taylor    public static boolean cancelFailedToDeliverNotification(Intent intent, Context context) {
164395817b166d415114bac89ca0946c3717ae229526Tom Taylor        if (MessagingNotification.isFailedToDeliver(intent)) {
164472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Cancel any failed message notifications
164572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            MessagingNotification.cancelNotification(context,
164672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        MessagingNotification.MESSAGE_FAILED_NOTIFICATION_ID);
164772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return true;
164872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
164972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return false;
165072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
165172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
165295817b166d415114bac89ca0946c3717ae229526Tom Taylor    public static boolean cancelFailedDownloadNotification(Intent intent, Context context) {
165395817b166d415114bac89ca0946c3717ae229526Tom Taylor        if (MessagingNotification.isFailedToDownload(intent)) {
165495817b166d415114bac89ca0946c3717ae229526Tom Taylor            // Cancel any failed download notifications
165595817b166d415114bac89ca0946c3717ae229526Tom Taylor            MessagingNotification.cancelNotification(context,
165695817b166d415114bac89ca0946c3717ae229526Tom Taylor                        MessagingNotification.DOWNLOAD_FAILED_NOTIFICATION_ID);
165795817b166d415114bac89ca0946c3717ae229526Tom Taylor            return true;
165895817b166d415114bac89ca0946c3717ae229526Tom Taylor        }
165995817b166d415114bac89ca0946c3717ae229526Tom Taylor        return false;
166095817b166d415114bac89ca0946c3717ae229526Tom Taylor    }
166195817b166d415114bac89ca0946c3717ae229526Tom Taylor
166272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
166372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onCreate(Bundle savedInstanceState) {
166472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onCreate(savedInstanceState);
166572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
166672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        setContentView(R.layout.compose_message_activity);
166772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        setProgressBarVisibility(false);
166872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
16696cc8b68c6b0956c51601065536f1dcd0494eef6eTom Taylor        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
16706cc8b68c6b0956c51601065536f1dcd0494eef6eTom Taylor                WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
167108c99d3e1045d9d5dd27d0845e0647d7664bfb4fMark Wagner
167272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Initialize members for UI elements.
167372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        initResourceRefs();
167472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
167572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mContentResolver = getContentResolver();
167672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mBackgroundQueryHandler = new BackgroundQueryHandler(mContentResolver);
1677b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
1678812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        initialize(savedInstanceState);
1679812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1680812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (TRACE) {
1681812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            android.os.Debug.startMethodTracing("compose");
1682812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
1683812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
1684812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1685812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    private void showSubjectEditor(boolean show) {
1686b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1687b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang            log("showSubjectEditor: " + show);
1688b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        }
1689b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang
1690812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (mSubjectTextEditor == null) {
1691812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            // Don't bother to initialize the subject editor if
1692812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            // we're just going to hide it.
1693812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            if (show == false) {
1694812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                return;
1695812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            }
1696812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            mSubjectTextEditor = (EditText)findViewById(R.id.subject);
1697b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        }
1698b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang
1699b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        mSubjectTextEditor.setOnKeyListener(show ? mSubjectKeyListener : null);
1700b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang
1701b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        if (show) {
1702812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            mSubjectTextEditor.addTextChangedListener(mSubjectEditorWatcher);
1703b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang        } else {
1704b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang            mSubjectTextEditor.removeTextChangedListener(mSubjectEditorWatcher);
1705812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
1706b22b30999e7d65d9a9a1991c1e409315a2c5ba99Wei Huang
1707812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        mSubjectTextEditor.setText(mWorkingMessage.getSubject());
1708812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        mSubjectTextEditor.setVisibility(show ? View.VISIBLE : View.GONE);
1709812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        hideOrShowTopPanel();
1710812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
1711812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1712812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    private void hideOrShowTopPanel() {
1713812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        boolean anySubViewsVisible = (isSubjectEditorVisible() || isRecipientsEditorVisible());
1714812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        mTopPanel.setVisibility(anySubViewsVisible ? View.VISIBLE : View.GONE);
1715812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    }
1716812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
171707d483e5da80176484bff536d118cc061f28e586Tom Taylor    public void initialize(Bundle savedInstanceState) {
1718812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        Intent intent = getIntent();
1719812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1720b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // Create a new empty working message.
1721b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage = WorkingMessage.createEmpty(this);
172272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
172372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Read parameters or previously saved state of this activity.
1724812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        initActivityState(savedInstanceState, intent);
172572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
172609a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        log("initialize: savedInstanceState = " + savedInstanceState +
172709a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                " intent = " + intent +
172809a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                " mConversation = " + mConversation);
172972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
173095817b166d415114bac89ca0946c3717ae229526Tom Taylor        if (cancelFailedToDeliverNotification(getIntent(), this)) {
173172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Show a pop-up dialog to inform user the message was
173272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // failed to deliver.
1733b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            undeliveredMessageDialog(getMessageDate(null));
173472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
173595817b166d415114bac89ca0946c3717ae229526Tom Taylor        cancelFailedDownloadNotification(getIntent(), this);
173628433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
17375d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // Set up the message history ListAdapter
17385d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        initMessageList();
17395d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project
174007e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        // Load the draft for this thread, if we aren't already handling
174107e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        // existing data, such as a shared picture or forwarded message.
174261138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor        boolean isForwardedMessage = false;
174361138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor        if (!handleSendIntent(intent)) {
174461138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            isForwardedMessage = handleForwardedMessage();
174561138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            if (!isForwardedMessage) {
174661138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor                loadDraft();
174761138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            }
174807e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        }
17491d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1750984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        // Let the working message know what conversation it belongs to
1751ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mWorkingMessage.setConversation(mConversation);
17521d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1753984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        // Show the recipients editor if we don't have a valid thread. Hide it otherwise.
1754ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        if (mConversation.getThreadId() <= 0) {
1755d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            // Hide the recipients editor so the call to initRecipientsEditor won't get
1756d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            // short-circuited.
1757984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang            hideRecipientEditor();
175872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            initRecipientsEditor();
1759fc0070e2bd326b9a4290d62dcbf6d8ff29c6ae89Tom Taylor
1760fc0070e2bd326b9a4290d62dcbf6d8ff29c6ae89Tom Taylor            // Bring up the softkeyboard so the user can immediately enter recipients. This
1761fc0070e2bd326b9a4290d62dcbf6d8ff29c6ae89Tom Taylor            // call won't do anything on devices with a hard keyboard.
17626cc8b68c6b0956c51601065536f1dcd0494eef6eTom Taylor            getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
17636cc8b68c6b0956c51601065536f1dcd0494eef6eTom Taylor                    WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
1764984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        } else {
1765984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang            hideRecipientEditor();
176672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
17671d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
176872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        updateSendButtonState();
176972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1770b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        drawTopPanel();
1771b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        drawBottomPanel();
1772b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mAttachmentEditor.update(mWorkingMessage);
177372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
177472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Configuration config = getResources().getConfiguration();
177572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mIsKeyboardOpen = config.keyboardHidden == KEYBOARDHIDDEN_NO;
177672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mIsLandscape = config.orientation == Configuration.ORIENTATION_LANDSCAPE;
177772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        onKeyboardStateChanged(mIsKeyboardOpen);
177828433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
177909a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
178009a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            log("initialize: update title, mConversation=" + mConversation.toString());
178109a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
178209a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
17838b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        updateTitle(mConversation.getRecipients());
178461138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor
178561138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor        if (isForwardedMessage && isRecipientsEditorVisible()) {
178661138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            // The user is forwarding the message to someone. Put the focus on the
178761138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            // recipient editor rather than in the message editor.
178861138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor            mRecipientsEditor.requestFocus();
178961138063f3486c29a5bbda77fdf9423dcb26f949Tom Taylor        }
179072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
179172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1792812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    @Override
1793812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    protected void onNewIntent(Intent intent) {
1794812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        super.onNewIntent(intent);
1795812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1796f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang        setIntent(intent);
1797f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
1798d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor        Conversation conversation = null;
1799511d10f9bfb1aee1150bf2127ae03d7275706cc6Tom Taylor        mSentMessage = false;
1800812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1801812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        // If we have been passed a thread_id, use that to find our
1802812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        // conversation.
1803812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        long threadId = intent.getLongExtra("thread_id", 0);
1804d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor        Uri intentUri = intent.getData();
180588ee29139d831325875c8d4e05d3edf6fa05d510Wei Huang
1806d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor        boolean sameThread = false;
1807812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (threadId > 0) {
1808e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor            conversation = Conversation.get(this, threadId, false);
1809812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        } else {
1810d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            if (mConversation.getThreadId() == 0) {
1811d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                // We've got a draft. See if the new intent's recipient is the same as
1812d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                // the draft's recipient. First make sure the working recipients are synched
1813d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                // to the conversation.
1814d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                mWorkingMessage.syncWorkingRecipients();
1815d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                sameThread = mConversation.sameRecipient(intentUri);
1816d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            }
1817d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            if (!sameThread) {
1818d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                // Otherwise, try to get a conversation based on the
1819d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor                // data URI passed to our intent.
1820e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                conversation = Conversation.get(this, intentUri, false);
1821d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            }
1822812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
1823812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
182488ee29139d831325875c8d4e05d3edf6fa05d510Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1825d62ef06699b3ca5048c5642bd50300e9a2eb04a1Tom Taylor            log("onNewIntent: data=" + intentUri + ", thread_id extra is " + threadId);
182688ee29139d831325875c8d4e05d3edf6fa05d510Wei Huang            log("     new conversation=" + conversation + ", mConversation=" + mConversation);
182788ee29139d831325875c8d4e05d3edf6fa05d510Wei Huang        }
182888ee29139d831325875c8d4e05d3edf6fa05d510Wei Huang
1829436042159134e8ecbc57097340a5bd81f2912574Tom Taylor        if (conversation != null) {
1830436042159134e8ecbc57097340a5bd81f2912574Tom Taylor            // Don't let any markAsRead DB updates occur before we've loaded the messages for
1831436042159134e8ecbc57097340a5bd81f2912574Tom Taylor            // the thread.
1832436042159134e8ecbc57097340a5bd81f2912574Tom Taylor            conversation.blockMarkAsRead(true);
1833ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang
1834ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // this is probably paranoia to compare both thread_ids and recipient lists,
1835ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // but we want to make double sure because this is a last minute fix for Froyo
1836ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // and the previous code checked thread ids only.
1837ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // (we cannot just compare thread ids because there is a case where mConversation
1838ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // has a stale/obsolete thread id (=1) that could collide against the new thread_id(=1),
1839ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            // even though the recipient lists are different)
1840ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            sameThread = (conversation.getThreadId() == mConversation.getThreadId() &&
1841ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang                    conversation.equals(mConversation));
1842436042159134e8ecbc57097340a5bd81f2912574Tom Taylor        }
1843ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang
1844ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang        if (sameThread) {
1845ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang            log("onNewIntent: same conversation");
1846812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        } else {
1847812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1848812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                log("onNewIntent: different conversation, initialize...");
1849b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            }
185028267695b591d5d9cc176e5f199eb2aef3f9fcd3Tom Taylor            saveDraft();    // if we've got a draft, save it first
185128267695b591d5d9cc176e5f199eb2aef3f9fcd3Tom Taylor
1852812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            initialize(null);
1853f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang            loadMessageContent();
1854b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
18551d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
185672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
185772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
185872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
185972b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project    protected void onRestart() {
186072b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project        super.onRestart();
186172b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project
18625cbf11ad39767245f1a9ef467963d270f19a5fabTom Taylor        if (mWorkingMessage.isDiscarded()) {
1863e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            // If the message isn't worth saving, don't resurrect it. Doing so can lead to
1864e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            // a situation where a new incoming message gets the old thread id of the discarded
1865e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            // draft. This activity can end up displaying the recipients of the old message with
1866e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            // the contents of the new message. Recognize that dangerous situation and bail out
1867e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            // to the ConversationList where the user can enter this in a clean manner.
1868e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            if (mWorkingMessage.isWorthSaving()) {
1869e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor                mWorkingMessage.unDiscard();    // it was discarded in onStop().
18704d26623ce82230e8e7009adb921c5edea370a9e0Tom Taylor            } else if (isRecipientsEditorVisible()) {
1871e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor                goToConversationList();
1872e0958a47a7e8610b1233824f4a538d5c6c9e7543Tom Taylor            }
18735cbf11ad39767245f1a9ef467963d270f19a5fabTom Taylor        }
187472b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project    }
187572b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project
187672b7fda4ff5e94ba1a13c41601ac1cd61c0d6663The Android Open Source Project    @Override
187772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onStart() {
187872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onStart();
1879436042159134e8ecbc57097340a5bd81f2912574Tom Taylor        mConversation.blockMarkAsRead(true);
188072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
188172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        initFocus();
188272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
188372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Register a BroadcastReceiver to listen on HTTP I/O process.
188472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        registerReceiver(mHttpProgressReceiver, mHttpProgressFilter);
188572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1886f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang        loadMessageContent();
18875467f0f860d4fb32ac4d0b230e9c21f236e46e9bTom Taylor
18885467f0f860d4fb32ac4d0b230e9c21f236e46e9bTom Taylor        // Update the fasttrack info in case any of the recipients' contact info changed
18895467f0f860d4fb32ac4d0b230e9c21f236e46e9bTom Taylor        // while we were paused. This can happen, for example, if a user changes or adds
18905467f0f860d4fb32ac4d0b230e9c21f236e46e9bTom Taylor        // an avatar associated with a contact.
18915467f0f860d4fb32ac4d0b230e9c21f236e46e9bTom Taylor        mWorkingMessage.syncWorkingRecipients();
189209a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
189309a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
189409a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            log("onStart: update title, mConversation=" + mConversation.toString());
189509a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
189609a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
18978b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        updateTitle(mConversation.getRecipients());
1898f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang    }
1899f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
190007d483e5da80176484bff536d118cc061f28e586Tom Taylor    public void loadMessageContent() {
190172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        startMsgListQuery();
19022f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        updateSendFailedNotification();
1903b348f222ee27426e0a038232d2a5b4b863f7ad9cTom Taylor        drawBottomPanel();
19042f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project    }
19051d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
19062f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project    private void updateSendFailedNotification() {
1907ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        final long threadId = mConversation.getThreadId();
1908ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        if (threadId <= 0)
1909ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            return;
19101d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
19112f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        // updateSendFailedNotificationForThread makes a database call, so do the work off
19122f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        // of the ui thread.
19132f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        new Thread(new Runnable() {
19142f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            public void run() {
19152f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                MessagingNotification.updateSendFailedNotificationForThread(
1916ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick                        ComposeMessageActivity.this, threadId);
19172f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            }
19182f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        }).run();
191972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
192072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
192172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
192272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onSaveInstanceState(Bundle outState) {
192372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onSaveInstanceState(outState);
192472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
19251d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        outState.putString("recipients", getRecipients().serialize());
192672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1927b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage.writeStateToBundle(outState);
192872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
192972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mExitOnSent) {
193072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            outState.putBoolean("exit_on_sent", mExitOnSent);
193172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
193272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
193372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
193472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
1935d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang    protected void onResume() {
1936d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        super.onResume();
1937d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang
1938d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        // OLD: get notified of presence updates to update the titlebar.
1939d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        // NEW: we are using ContactHeaderWidget which displays presence, but updating presence
1940d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        //      there is out of our control.
1941d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        //Contact.startPresenceObserver();
1942d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang
1943d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        addRecipientsListeners();
19448b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner
194509a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
194609a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            log("onResume: update title, mConversation=" + mConversation.toString());
194709a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
194809a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang
19498b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        // There seems to be a bug in the framework such that setting the title
19508b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        // here gets overwritten to the original title.  Do this delayed as a
19518b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        // workaround.
19528b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        mMessageListItemHandler.postDelayed(new Runnable() {
19538b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            public void run() {
19548b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                ContactList recipients = isRecipientsEditorVisible() ?
1955cab73c66f1b07a639cbb75b6510d425477cbcaecTom Taylor                        mRecipientsEditor.constructContactsFromInput() : getRecipients();
19568b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                updateTitle(recipients);
19578b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner            }
19588b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner        }, 100);
1959d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang    }
1960d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang
1961d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang    @Override
196272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onPause() {
196372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onPause();
1964812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
1965d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        // OLD: stop getting notified of presence updates to update the titlebar.
1966d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        // NEW: we are using ContactHeaderWidget which displays presence, but updating presence
1967d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        //      there is out of our control.
1968d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang        //Contact.stopPresenceObserver();
1969d9d7479a8c9e10b7b3f39137e28ed0f283e4a257Wei Huang
1970458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor        removeRecipientsListeners();
197172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
197272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
197372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
197472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onStop() {
197572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onStop();
19761d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
1977436042159134e8ecbc57097340a5bd81f2912574Tom Taylor        // Allow any blocked calls to update the thread's read status.
1978436042159134e8ecbc57097340a5bd81f2912574Tom Taylor        mConversation.blockMarkAsRead(false);
1979436042159134e8ecbc57097340a5bd81f2912574Tom Taylor
198072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mMsgListAdapter != null) {
19812f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            mMsgListAdapter.changeCursor(null);
198272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
198372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
1984812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
1985812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            log("onStop: save draft");
1986812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
1987cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        saveDraft();
1988cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick
198972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Cleanup the BroadcastReceiver.
199072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        unregisterReceiver(mHttpProgressReceiver);
199172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
199272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
199372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
199472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onDestroy() {
199572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (TRACE) {
199672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            android.os.Debug.stopMethodTracing();
199772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
19981d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
199972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onDestroy();
200072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
200172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
200272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
200372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onConfigurationChanged(Configuration newConfig) {
200472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        super.onConfigurationChanged(newConfig);
200572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (LOCAL_LOGV) {
200672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Log.v(TAG, "onConfigurationChanged: " + newConfig);
200772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20081d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
200972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mIsKeyboardOpen = newConfig.keyboardHidden == KEYBOARDHIDDEN_NO;
2010fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor        boolean isLandscape = newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE;
2011fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor        if (mIsLandscape != isLandscape) {
2012fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor            mIsLandscape = isLandscape;
2013fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor
2014fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor            // Have to re-layout the attachment editor because we have different layouts
2015fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor            // depending on whether we're portrait or landscape.
2016fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor            mAttachmentEditor.update(mWorkingMessage);
2017fa1c08f58afd8246b223c2a55a4ba0a6dac39526Tom Taylor        }
201872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        onKeyboardStateChanged(mIsKeyboardOpen);
201972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
202072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
202172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void onKeyboardStateChanged(boolean isKeyboardOpen) {
202272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the keyboard is hidden, don't show focus highlights for
202372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // things that cannot receive input.
202472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (isKeyboardOpen) {
202572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mRecipientsEditor != null) {
202672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mRecipientsEditor.setFocusableInTouchMode(true);
202772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
202872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mSubjectTextEditor != null) {
202972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSubjectTextEditor.setFocusableInTouchMode(true);
203072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
203172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextEditor.setFocusableInTouchMode(true);
203272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextEditor.setHint(R.string.type_to_compose_text_enter_to_send);
203372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
203472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mRecipientsEditor != null) {
203572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mRecipientsEditor.setFocusable(false);
203672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
203772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (mSubjectTextEditor != null) {
203872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSubjectTextEditor.setFocusable(false);
203972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
204072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextEditor.setFocusable(false);
204172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mTextEditor.setHint(R.string.open_keyboard_to_compose_message);
204272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
204372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
204472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
204572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
204672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onUserInteraction() {
204772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        checkPendingNotification();
204872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
204972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
205072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
205172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onWindowFocusChanged(boolean hasFocus) {
205272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (hasFocus) {
205372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            checkPendingNotification();
205472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
205572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
20561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
205772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
205872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onKeyDown(int keyCode, KeyEvent event) {
205972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch (keyCode) {
206072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DEL:
206172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if ((mMsgListAdapter != null) && mMsgListView.isFocused()) {
206272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    Cursor cursor;
206372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    try {
206472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        cursor = (Cursor) mMsgListView.getSelectedItem();
206572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    } catch (ClassCastException e) {
206672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Log.e(TAG, "Unexpected ClassCastException.", e);
206772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return super.onKeyDown(keyCode, event);
206872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
206972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
207072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (cursor != null) {
20713e10898d774b0005fc776865216651346503024bTom Taylor                        boolean locked = cursor.getInt(COLUMN_MMS_LOCKED) != 0;
207272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        DeleteMessageListener l = new DeleteMessageListener(
207372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                                cursor.getLong(COLUMN_ID),
20743e10898d774b0005fc776865216651346503024bTom Taylor                                cursor.getString(COLUMN_MSG_TYPE),
20753e10898d774b0005fc776865216651346503024bTom Taylor                                locked);
20763e10898d774b0005fc776865216651346503024bTom Taylor                        confirmDeleteDialog(l, locked);
207772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return true;
207872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
207972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
208072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
208172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_DPAD_CENTER:
208272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_ENTER:
208372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isPreparedForSending()) {
208472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    confirmSendMessageIfNeeded();
208572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return true;
208672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
208772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
208872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case KeyEvent.KEYCODE_BACK:
208972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                exitComposeMessageActivity(new Runnable() {
209072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    public void run() {
209172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        finish();
209272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
209372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                });
209472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return true;
209572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
20961d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
209772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return super.onKeyDown(keyCode, event);
209872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
209972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
210072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void exitComposeMessageActivity(final Runnable exit) {
2101cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        // If the message is empty, just quit -- finishing the
2102cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        // activity will cause an empty draft to be deleted.
2103b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (!mWorkingMessage.isWorthSaving()) {
2104cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick            exit.run();
2105cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick            return;
210672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
21071d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
210878f81825431c8c52cad57bc4a363747533a701abWei Huang        if (isRecipientsEditorVisible() &&
210978f81825431c8c52cad57bc4a363747533a701abWei Huang                !mRecipientsEditor.hasValidRecipient(mWorkingMessage.requiresMms())) {
211078f81825431c8c52cad57bc4a363747533a701abWei Huang            MessageUtils.showDiscardDraftConfirmDialog(this, new DiscardDraftListener());
2111cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick            return;
2112cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        }
2113cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick
2114cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        mToastForDraftSave = true;
2115cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        exit.run();
211672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
211772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
211872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void goToConversationList() {
211972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        finish();
212072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        startActivity(new Intent(this, ConversationList.class));
212172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
212272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2123984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang    private void hideRecipientEditor() {
2124984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        if (mRecipientsEditor != null) {
212507cd34eef6ff14e823a3cedfadadeb1c6e535812Tom Taylor            mRecipientsEditor.removeTextChangedListener(mRecipientsWatcher);
2126984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang            mRecipientsEditor.setVisibility(View.GONE);
2127984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang            hideOrShowTopPanel();
2128984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        }
2129984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang    }
2130984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang
213172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isRecipientsEditorVisible() {
213272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return (null != mRecipientsEditor)
213372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    && (View.VISIBLE == mRecipientsEditor.getVisibility());
213472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
213572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
213672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isSubjectEditorVisible() {
213772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return (null != mSubjectTextEditor)
213872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    && (View.VISIBLE == mSubjectTextEditor.getVisibility());
213972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
21401d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2141b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    public void onAttachmentChanged() {
2142f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        // Have to make sure we're on the UI thread. This function can be called off of the UI
2143f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        // thread when we're adding multi-attachments
2144f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        runOnUiThread(new Runnable() {
2145f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            public void run() {
2146f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                drawBottomPanel();
2147f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                updateSendButtonState();
2148f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                mAttachmentEditor.update(mWorkingMessage);
2149f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            }
2150f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        });
215172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
215272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2153f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor    public void onProtocolChanged(final boolean mms) {
2154f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        // Have to make sure we're on the UI thread. This function can be called off of the UI
2155f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        // thread when we're adding multi-attachments
2156f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        runOnUiThread(new Runnable() {
2157f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            public void run() {
2158f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                toastConvertInfo(mms);
2159f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                setSendButtonText(mms);
2160f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            }
2161f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        });
2162b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen    }
2163b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen
2164b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen    private void setSendButtonText(boolean isMms) {
2165b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        Button sendButton = mSendButton;
2166b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        sendButton.setText(R.string.send);
2167b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen
2168b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        if (isMms) {
2169b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            // Create and append the "MMS" text in a smaller font than the "Send" text.
2170b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            sendButton.append("\n");
2171b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            SpannableString spannable = new SpannableString(getString(R.string.mms));
2172b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            int mmsTextSize = (int) (sendButton.getTextSize() * 0.75f);
2173b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            spannable.setSpan(new AbsoluteSizeSpan(mmsTextSize), 0, spannable.length(), 0);
2174b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            sendButton.append(spannable);
2175b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            mTextCounter.setText("");
2176b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        }
2177b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
2178424b9e2a1f9f186bfa0171872bbdb96b7be24d8dTom Taylor
2179c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    Runnable mResetMessageRunnable = new Runnable() {
2180c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        public void run() {
2181c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor            resetMessage();
2182c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        }
2183c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    };
2184c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor
2185c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    public void onPreMessageSent() {
2186c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        runOnUiThread(mResetMessageRunnable);
2187c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    }
21881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2189ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    public void onMessageSent() {
2190b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // If we already have messages in the list adapter, it
2191b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // will be auto-requerying; don't thrash another query in.
2192b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (mMsgListAdapter.getCount() == 0) {
2193b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            startMsgListQuery();
2194b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
2195b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
21961d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2197c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    public void onMaxPendingMessagesReached() {
2198c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        saveDraft();
2199c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor
2200c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        runOnUiThread(new Runnable() {
2201c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor            public void run() {
2202c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor                Toast.makeText(ComposeMessageActivity.this, R.string.too_many_unsent_mms,
2203c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor                        Toast.LENGTH_LONG).show();
2204c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor            }
2205c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor        });
2206c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor    }
2207c44a89a040956a7b9635de4a9bcf1d7230692750Tom Taylor
220810eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    public void onAttachmentError(final int error) {
220910eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        runOnUiThread(new Runnable() {
221010eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            public void run() {
221110eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                handleAddAttachmentError(error, R.string.type_picture);
22120d4645de339b4681d18198ba7451e7b8807116f9Tom Taylor                onMessageSent();        // now requery the list of messages
221310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor            }
221410eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor        });
221510eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor    }
221610eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor
221772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // We don't want to show the "call" option unless there is only one
221872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // recipient and it's a phone number.
221972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isRecipientCallable() {
22201d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        ContactList recipients = getRecipients();
22211d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        return (recipients.size() == 1 && !recipients.containsEmail());
222272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22231d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
222472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void dialRecipient() {
22251d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        String number = getRecipients().get(0).getNumber();
2226f9ed50ad8005a797230392d79a2cafbf82d026beTom Taylor        Intent dialIntent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + number));
222772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        startActivity(dialIntent);
222872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22291d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
223072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
223172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onPrepareOptionsMenu(Menu menu) {
223272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        menu.clear();
223372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
223472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (isRecipientCallable()) {
223572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_CALL_RECIPIENT, 0, R.string.menu_call).setIcon(
22366be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                    R.drawable.ic_menu_call);
223772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22381d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
223972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Only add the "View contact" menu item when there's a single recipient and that
224072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // recipient is someone in contacts.
22411d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        ContactList recipients = getRecipients();
22421d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        if (recipients.size() == 1 && recipients.get(0).existsInDatabase()) {
224372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_VIEW_CONTACT, 0, R.string.menu_view_contact).setIcon(
224472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    R.drawable.ic_menu_contact);
224572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
224672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
224786a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylor        if (MmsConfig.getMmsEnabled()) {
2248836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project            if (!isSubjectEditorVisible()) {
2249bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project                menu.add(0, MENU_ADD_SUBJECT, 0, R.string.add_subject).setIcon(
22506be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                        R.drawable.ic_menu_edit);
2251bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project            }
225272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2253b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            if (!mWorkingMessage.hasAttachment()) {
2254bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project                menu.add(0, MENU_ADD_ATTACHMENT, 0, R.string.add_attachment).setIcon(
2255bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project                        R.drawable.ic_menu_attachment);
2256bd09a4b8c2d1f922f1459c4d7b61e7e87ed4ddf3The Android Open Source Project            }
225772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
22581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
225972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (isPreparedForSending()) {
226072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_SEND, 0, R.string.send).setIcon(android.R.drawable.ic_menu_send);
226172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
226272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
226372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        menu.add(0, MENU_INSERT_SMILEY, 0, R.string.menu_insert_smiley).setIcon(
22646be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                R.drawable.ic_menu_emoticons);
226572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
226634390cc77dd159b3aec558e26d4fb0674104dae4Ficus Kirkpatrick        if (mMsgListAdapter.getCount() > 0) {
226772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Removed search as part of b/1205708
226872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            //menu.add(0, MENU_SEARCH, 0, R.string.menu_search).setIcon(
226972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            //        R.drawable.ic_menu_search);
22702f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            Cursor cursor = mMsgListAdapter.getCursor();
22712f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project            if ((null != cursor) && (cursor.getCount() > 0)) {
227272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                menu.add(0, MENU_DELETE_THREAD, 0, R.string.delete_thread).setIcon(
227372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    android.R.drawable.ic_menu_delete);
227472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
227572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
227672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            menu.add(0, MENU_DISCARD, 0, R.string.discard).setIcon(android.R.drawable.ic_menu_delete);
227772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
227872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
227972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        menu.add(0, MENU_CONVERSATION_LIST, 0, R.string.all_threads).setIcon(
22806be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                R.drawable.ic_menu_friendslist);
228172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
228272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        buildAddAddressToContactMenuItem(menu);
228372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
228472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
22851d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
228672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void buildAddAddressToContactMenuItem(Menu menu) {
22871d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // Look for the first recipient we don't have a contact for and create a menu item to
22881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // add the number to contacts.
22891d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        for (Contact c : getRecipients()) {
22908fe0dc7bde259488a917f3c246a5020b992cfe8aTom Taylor            if (!c.existsInDatabase() && canAddToContacts(c)) {
22911d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                Intent intent = ConversationList.createAddContactIntent(c.getNumber());
22921d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                menu.add(0, MENU_ADD_ADDRESS_TO_CONTACTS, 0, R.string.menu_add_to_contacts)
22931d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    .setIcon(android.R.drawable.ic_menu_add)
22941d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    .setIntent(intent);
22951d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                break;
229672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
229772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
229872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
229972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
230072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
230172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onOptionsItemSelected(MenuItem item) {
230272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch (item.getItemId()) {
230372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_ADD_SUBJECT:
2304b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                showSubjectEditor(true);
2305396a06af4e393f5aab3864c43392a67c60715d38Tom Taylor                mWorkingMessage.setSubject("", true);
230672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mSubjectTextEditor.requestFocus();
230772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
230872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_ADD_ATTACHMENT:
230972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Launch the add-attachment list dialog
2310d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                showAddAttachmentDialog(false);
231172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
231272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_DISCARD:
2313b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                mWorkingMessage.discard();
231472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                finish();
231572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
231672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_SEND:
231772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isPreparedForSending()) {
231872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    confirmSendMessageIfNeeded();
231972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
232072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
232172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_SEARCH:
232272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                onSearchRequested();
232372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
232472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_DELETE_THREAD:
23253e10898d774b0005fc776865216651346503024bTom Taylor                confirmDeleteThread(mConversation.getThreadId());
232672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
232772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_CONVERSATION_LIST:
232872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                exitComposeMessageActivity(new Runnable() {
232972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    public void run() {
233072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        goToConversationList();
233172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
233272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                });
233372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
233472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_CALL_RECIPIENT:
233572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                dialRecipient();
233672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
233772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_INSERT_SMILEY:
233872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                showSmileyDialog();
233972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
23401d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            case MENU_VIEW_CONTACT: {
234172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // View the contact for the first (and only) recipient.
23421d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                ContactList list = getRecipients();
23431d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                if (list.size() == 1 && list.get(0).existsInDatabase()) {
23441d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick                    Uri contactUri = list.get(0).getUri();
2345dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
2346dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
2347dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor                    startActivity(intent);
234872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
234972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
23501d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            }
235172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case MENU_ADD_ADDRESS_TO_CONTACTS:
235260d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                mAddContactIntent = item.getIntent();
235360d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                startActivityForResult(mAddContactIntent, REQUEST_CODE_ADD_CONTACT);
235460d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                break;
235572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
235672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
235772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
235872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
235972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
23603e10898d774b0005fc776865216651346503024bTom Taylor    private void confirmDeleteThread(long threadId) {
23613e10898d774b0005fc776865216651346503024bTom Taylor        Conversation.startQueryHaveLockedMessages(mBackgroundQueryHandler,
23623e10898d774b0005fc776865216651346503024bTom Taylor                threadId, ConversationList.HAVE_LOCKED_MESSAGES_TOKEN);
23633e10898d774b0005fc776865216651346503024bTom Taylor    }
23643e10898d774b0005fc776865216651346503024bTom Taylor
23656be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor//    static class SystemProperties { // TODO, temp class to get unbundling working
23666be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor//        static int getInt(String s, int value) {
23676be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor//            return value;       // just return the default value or now
23686be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor//        }
23696be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor//    }
23706be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor
237164d0ce47710fb671b0d4d7f2e8789757085eeac9Chih-Chung Chang    private int getVideoCaptureDurationLimit() {
23724011f521ee944725d09106d96968b104c0c0eaacJames Dong        return CamcorderProfile.get(CamcorderProfile.QUALITY_LOW).duration;
237364d0ce47710fb671b0d4d7f2e8789757085eeac9Chih-Chung Chang    }
237464d0ce47710fb671b0d4d7f2e8789757085eeac9Chih-Chung Chang
2375d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor    private void addAttachment(int type, boolean replace) {
2376d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        // Calculate the size of the current slide if we're doing a replace so the
2377d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        // slide size can optionally be used in computing how much room is left for an attachment.
2378d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        int currentSlideSize = 0;
2379d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        SlideshowModel slideShow = mWorkingMessage.getSlideshow();
2380d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        if (replace && slideShow != null) {
2381d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor            SlideModel slide = slideShow.get(0);
2382d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor            currentSlideSize = slide.getSlideSize();
2383d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor        }
238472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch (type) {
238572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.ADD_IMAGE:
238671cf4b0b2901590fffd04c7cdeba8d1c05c4c214Ficus Kirkpatrick                MessageUtils.selectImage(this, REQUEST_CODE_ATTACH_IMAGE);
238772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
238872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
238972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.TAKE_PICTURE: {
239072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
239134b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang
239234b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang                intent.putExtra(MediaStore.EXTRA_OUTPUT, Mms.ScrapSpace.CONTENT_URI);
239371cf4b0b2901590fffd04c7cdeba8d1c05c4c214Ficus Kirkpatrick                startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);
239472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
239534b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            }
239672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
239772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.ADD_VIDEO:
239871cf4b0b2901590fffd04c7cdeba8d1c05c4c214Ficus Kirkpatrick                MessageUtils.selectVideo(this, REQUEST_CODE_ATTACH_VIDEO);
239972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
240072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
240172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.RECORD_VIDEO: {
240228433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                // Set video size limit. Subtract 1K for some text.
240310eed0e3020e3eb0612747fe39e0f6117222dd95Tom Taylor                long sizeLimit = MmsConfig.getMaxMessageSize() - SlideshowModel.SLIDESHOW_SLOP;
2404d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                if (slideShow != null) {
2405d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    sizeLimit -= slideShow.getCurrentMessageSize();
2406d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor
2407d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    // We're about to ask the camera to capture some video which will
2408d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    // eventually replace the content on the current slide. Since the current
2409d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    // slide already has some content (which was subtracted out just above)
2410d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    // and that content is going to get replaced, we can add the size of the
2411d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    // current slide into the available space used to capture a video.
2412d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                    sizeLimit += currentSlideSize;
241328433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                }
241428433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                if (sizeLimit > 0) {
241564d0ce47710fb671b0d4d7f2e8789757085eeac9Chih-Chung Chang                    int durationLimit = getVideoCaptureDurationLimit();
241628433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                    Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
241728433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                    intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
24186be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                    intent.putExtra("android.intent.extra.sizeLimit", sizeLimit);
24196be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor                    intent.putExtra("android.intent.extra.durationLimit", durationLimit);
242028433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                    startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO);
242128433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                }
242228433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                else {
242328433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                    Toast.makeText(this,
242428433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                            getString(R.string.message_too_big_for_video),
242528433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                            Toast.LENGTH_SHORT).show();
242628433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor                }
242772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
242828433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor            break;
242972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
243072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.ADD_SOUND:
243171cf4b0b2901590fffd04c7cdeba8d1c05c4c214Ficus Kirkpatrick                MessageUtils.selectAudio(this, REQUEST_CODE_ATTACH_SOUND);
243272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
243372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
243472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case AttachmentTypeSelectorAdapter.RECORD_SOUND:
243571cf4b0b2901590fffd04c7cdeba8d1c05c4c214Ficus Kirkpatrick                MessageUtils.recordSound(this, REQUEST_CODE_RECORD_SOUND);
243672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
243772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2438b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            case AttachmentTypeSelectorAdapter.ADD_SLIDESHOW:
2439b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                editSlideshow();
244072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
244172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
244272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
244372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
244472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
244572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
244672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2447d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor    private void showAddAttachmentDialog(final boolean replace) {
244872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(this);
2449836945de572ac80fd6f6a7bf59036d4cce801410The Android Open Source Project        builder.setIcon(R.drawable.ic_dialog_attach);
245072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setTitle(R.string.add_attachment);
245172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
245295e96df81536897f5856e9d33d5eccd54210d87aTom Taylor        if (mAttachmentTypeSelectorAdapter == null) {
245395e96df81536897f5856e9d33d5eccd54210d87aTom Taylor            mAttachmentTypeSelectorAdapter = new AttachmentTypeSelectorAdapter(
245495e96df81536897f5856e9d33d5eccd54210d87aTom Taylor                    this, AttachmentTypeSelectorAdapter.MODE_WITH_SLIDESHOW);
245595e96df81536897f5856e9d33d5eccd54210d87aTom Taylor        }
24564d620299628c41f9149024f0cf9f42d008aedcf5Tom Taylor        builder.setAdapter(mAttachmentTypeSelectorAdapter, new DialogInterface.OnClickListener() {
245772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onClick(DialogInterface dialog, int which) {
2458d94aa5fd212ff690e0527e587a1aef8313fca064Tom Taylor                addAttachment(mAttachmentTypeSelectorAdapter.buttonToCommand(which), replace);
245972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
246072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        });
246172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
246272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
246372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
246472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
246572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    @Override
246672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
246734b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang        if (DEBUG) {
246834b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            log("onActivityResult: requestCode=" + requestCode
246972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    + ", resultCode=" + resultCode + ", data=" + data);
247072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
2471c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor        mWaitingForSubActivity = false;          // We're back!
2472c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor        if (mWorkingMessage.isFakeMmsForDraft()) {
2473c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor            // We no longer have to fake the fact we're an Mms. At this point we are or we aren't,
2474c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor            // based on attachments and other Mms attrs.
2475c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor            mWorkingMessage.removeFakeMmsForDraft();
2476c7b4497d1129fbfc1a69ee3c5a30e28153afd3e8Tom Taylor        }
24771d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2478ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        // If there's no data (because the user didn't select a picture and
2479ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        // just hit BACK, for example), there's nothing to do.
248034b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang        if (requestCode != REQUEST_CODE_TAKE_PICTURE) {
248134b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            if (data == null) {
248234b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang                return;
248334b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            }
248434b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang        } else if (resultCode != RESULT_OK){
248534b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            if (DEBUG) log("onActivityResult: bail due to resultCode=" + resultCode);
2486ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            return;
2487ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        }
24881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
248972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        switch(requestCode) {
249072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case REQUEST_CODE_CREATE_SLIDESHOW:
2491b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                if (data != null) {
249277098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                    WorkingMessage newMessage = WorkingMessage.load(this, data.getData());
249377098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                    if (newMessage != null) {
249477098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                        mWorkingMessage = newMessage;
249577098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                        mWorkingMessage.setConversation(mConversation);
249677098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                        mAttachmentEditor.update(mWorkingMessage);
249777098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                        drawTopPanel();
249877098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                        updateSendButtonState();
249977098247e64fa81b7f52457e364b81a8dbcb499aTom Taylor                    }
250072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
250172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
250272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
250334b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            case REQUEST_CODE_TAKE_PICTURE: {
25040aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                // create a file based uri and pass to addImage(). We want to read the JPEG
25050aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                // data directly from file (using UriImage) instead of decoding it into a Bitmap,
25060aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                // which takes up too much memory and could easily lead to OOM.
25070aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                File file = new File(Mms.ScrapSpace.SCRAP_FILE_PATH);
25080aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                Uri uri = Uri.fromFile(file);
25090aef1a199b5a702f4a0acbbd27c936115ed7ab64Wei Huang                addImage(uri, false);
251072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
251134b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            }
251272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
251334b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            case REQUEST_CODE_ATTACH_IMAGE: {
2514edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                addImage(data.getData(), false);
251572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
251634b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            }
251772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
251872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case REQUEST_CODE_TAKE_VIDEO:
251972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case REQUEST_CODE_ATTACH_VIDEO:
2520edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                addVideo(data.getData(), false);
252172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
252272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
252334b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            case REQUEST_CODE_ATTACH_SOUND: {
2524b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                Uri uri = (Uri) data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
2525b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                if (Settings.System.DEFAULT_RINGTONE_URI.equals(uri)) {
2526b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                    break;
252772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
2528b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                addAudio(uri);
2529b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                break;
253034b48c16fc630bca88b9c4657bd19e6718a8f83eWei Huang            }
253172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2532b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            case REQUEST_CODE_RECORD_SOUND:
2533b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                addAudio(data.getData());
253472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
253572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
25363b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            case REQUEST_CODE_ECM_EXIT_DIALOG:
25373b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                boolean outOfEmergencyMode = data.getBooleanExtra(EXIT_ECM_RESULT, false);
25383b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                if (outOfEmergencyMode) {
25393b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                    sendMessage(false);
25403b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                }
25413b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                break;
25423b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng
254360d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor            case REQUEST_CODE_ADD_CONTACT:
254460d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                // The user just added a new contact. We saved the contact info in
254560d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                // mAddContactIntent. Get the contact and force our cached contact to
254660d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                // get reloaded with the new info (such as contact name). After the
254760d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                // contact is reloaded, the function onUpdate() in this file will get called
254860d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                // and it will update the title bar, etc.
254960d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                if (mAddContactIntent != null) {
255060d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    String address =
255160d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                        mAddContactIntent.getStringExtra(ContactsContract.Intents.Insert.EMAIL);
255260d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    if (address == null) {
255360d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                        address =
255460d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                            mAddContactIntent.getStringExtra(ContactsContract.Intents.Insert.PHONE);
255560d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    }
255660d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    if (address != null) {
255760d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                        Contact contact = Contact.get(address, false);
255860d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                        if (contact != null) {
255960d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                            contact.reload();
256060d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                        }
256160d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                    }
256260d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                }
256360d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor                break;
256460d7fa5f74463f22fe9a4cd81c0b2fcc95be7c09Tom Taylor
256572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            default:
256672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // TODO
256772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
256872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
256972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
257072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
257172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final ResizeImageResultCallback mResizeImageCallback = new ResizeImageResultCallback() {
2572b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // TODO: make this produce a Uri, that's what we want anyway
2573edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        public void onResizeResult(PduPart part, boolean append) {
257472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (part == null) {
2575b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                handleAddAttachmentError(WorkingMessage.UNKNOWN_ERROR, R.string.type_picture);
257672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return;
257772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25781d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2579b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            Context context = ComposeMessageActivity.this;
2580b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            PduPersister persister = PduPersister.getPduPersister(context);
2581b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            int result;
25821d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
258316f98e62c279550854e665e25c212ea0b04a6b6bTom Taylor            Uri messageUri = mWorkingMessage.saveAsMms(true);
258472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            try {
2585b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                Uri dataUri = persister.persistPart(part, ContentUris.parseId(messageUri));
2586edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                result = mWorkingMessage.setAttachment(WorkingMessage.IMAGE, dataUri, append);
2587812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
2588812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                    log("ResizeImageResultCallback: dataUri=" + dataUri);
2589812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                }
259072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } catch (MmsException e) {
2591b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                result = WorkingMessage.UNKNOWN_ERROR;
259272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
25931d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2594b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            handleAddAttachmentError(result, R.string.type_picture);
259572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
259672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
259772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2598a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor    private void handleAddAttachmentError(final int error, final int mediaTypeStringId) {
2599b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (error == WorkingMessage.OK) {
2600b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return;
2601b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
26021d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2603a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor        runOnUiThread(new Runnable() {
2604a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor            public void run() {
2605a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                Resources res = getResources();
2606a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                String mediaType = res.getString(mediaTypeStringId);
2607a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                String title, message;
2608a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor
2609a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                switch(error) {
2610a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                case WorkingMessage.UNKNOWN_ERROR:
2611a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    message = res.getString(R.string.failed_to_add_media, mediaType);
2612a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    Toast.makeText(ComposeMessageActivity.this, message, Toast.LENGTH_SHORT).show();
2613a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    return;
2614a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                case WorkingMessage.UNSUPPORTED_TYPE:
2615a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    title = res.getString(R.string.unsupported_media_format, mediaType);
2616a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    message = res.getString(R.string.select_different_media, mediaType);
2617a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    break;
2618a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                case WorkingMessage.MESSAGE_SIZE_EXCEEDED:
2619a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    title = res.getString(R.string.exceed_message_size_limitation, mediaType);
2620a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    message = res.getString(R.string.failed_to_add_media, mediaType);
2621a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    break;
2622a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                case WorkingMessage.IMAGE_TOO_LARGE:
2623a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    title = res.getString(R.string.failed_to_resize_image);
2624a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    message = res.getString(R.string.resize_image_error_information);
2625a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    break;
2626a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                default:
2627a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                    throw new IllegalArgumentException("unknown error " + error);
2628a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                }
2629b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
2630a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor                MessageUtils.showErrorDialog(ComposeMessageActivity.this, title, message);
2631a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor            }
2632a2023c74813d4bee578462d4d4470f657d3e07deTom Taylor        });
2633b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
26341d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2635edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor    private void addImage(Uri uri, boolean append) {
2636812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
2637812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            log("addImage: append=" + append + ", uri=" + uri);
2638812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
2639812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
2640edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        int result = mWorkingMessage.setAttachment(WorkingMessage.IMAGE, uri, append);
26411d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2642f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson        if (result == WorkingMessage.IMAGE_TOO_LARGE ||
2643f79b803adc0cee3778cf6aac52d203896cde5d95Christian Gustafsson            result == WorkingMessage.MESSAGE_SIZE_EXCEEDED) {
2644812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
2645812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                log("addImage: resize image " + uri);
2646812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            }
264734cba2ee7ea396870297dc7fe4a78a7a5357c859Tom Taylor            MessageUtils.resizeImageAsync(this,
264834cba2ee7ea396870297dc7fe4a78a7a5357c859Tom Taylor                    uri, mAttachmentEditorHandler, mResizeImageCallback, append);
2649b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return;
265072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
2651b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        handleAddAttachmentError(result, R.string.type_picture);
265272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
265372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2654edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor    private void addVideo(Uri uri, boolean append) {
2655e456dc390dc5f3eeb3dd4b4f37d9bd4a74efe6c8Satish Roddom        if (uri != null) {
2656edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            int result = mWorkingMessage.setAttachment(WorkingMessage.VIDEO, uri, append);
2657e456dc390dc5f3eeb3dd4b4f37d9bd4a74efe6c8Satish Roddom            handleAddAttachmentError(result, R.string.type_video);
2658e456dc390dc5f3eeb3dd4b4f37d9bd4a74efe6c8Satish Roddom        }
265972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
26601d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2661b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private void addAudio(Uri uri) {
2662edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        int result = mWorkingMessage.setAttachment(WorkingMessage.AUDIO, uri, false);
2663b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        handleAddAttachmentError(result, R.string.type_audio);
2664b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
2665b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
266607e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick    private boolean handleForwardedMessage() {
2667b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        Intent intent = getIntent();
26681d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
266907e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        // If this is a forwarded message, it will have an Intent extra
267007e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        // indicating so.  If not, bail out.
2671b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (intent.getBooleanExtra("forwarded_message", false) == false) {
267207e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick            return false;
267307e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        }
267407e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick
2675b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        Uri uri = intent.getParcelableExtra("msg_uri");
2676f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
2677f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang        if (Log.isLoggable(LogTag.APP, Log.DEBUG)) {
2678f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang            log("handle forwarded message " + uri);
2679f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang        }
2680f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
2681b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (uri != null) {
2682b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mWorkingMessage = WorkingMessage.load(this, uri);
2683396a06af4e393f5aab3864c43392a67c60715d38Tom Taylor            mWorkingMessage.setSubject(intent.getStringExtra("subject"), false);
2684b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        } else {
2685b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mWorkingMessage.setText(intent.getStringExtra("sms_body"));
268607e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        }
26871d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
26884c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang        // let's clear the message thread for forwarded messages
26894c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang        mMsgListAdapter.changeCursor(null);
26904c86b97e7aa0489813c34c13546fbbbcaa7b4897Wei Huang
269107e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        return true;
269207e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick    }
26931d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
269407e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick    private boolean handleSendIntent(Intent intent) {
269572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Bundle extras = intent.getExtras();
2696edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        if (extras == null) {
269707e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick            return false;
269872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
26991d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2700f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor        final String mimeType = intent.getType();
2701edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        String action = intent.getAction();
2702edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        if (Intent.ACTION_SEND.equals(action)) {
2703edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            if (extras.containsKey(Intent.EXTRA_STREAM)) {
2704edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                Uri uri = (Uri)extras.getParcelable(Intent.EXTRA_STREAM);
2705923c4c7e9afb8e364d4a93afa0eb6394485d3637Dmitri Plotnikov                addAttachment(mimeType, uri, false);
2706edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                return true;
2707edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            } else if (extras.containsKey(Intent.EXTRA_TEXT)) {
2708edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                mWorkingMessage.setText(extras.getString(Intent.EXTRA_TEXT));
2709edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                return true;
2710edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            }
2711edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        } else if (Intent.ACTION_SEND_MULTIPLE.equals(action) &&
2712edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                extras.containsKey(Intent.EXTRA_STREAM)) {
2713f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            SlideshowModel slideShow = mWorkingMessage.getSlideshow();
2714f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            final ArrayList<Parcelable> uris = extras.getParcelableArrayList(Intent.EXTRA_STREAM);
2715f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            int currentSlideCount = slideShow != null ? slideShow.size() : 0;
2716f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            int importCount = uris.size();
2717f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            if (importCount + currentSlideCount > SlideshowEditor.MAX_SLIDE_NUM) {
2718f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                importCount = Math.min(SlideshowEditor.MAX_SLIDE_NUM - currentSlideCount,
2719f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                        importCount);
2720f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                Toast.makeText(ComposeMessageActivity.this,
2721f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                        getString(R.string.too_many_attachments,
2722f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                                SlideshowEditor.MAX_SLIDE_NUM, importCount),
2723f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                                Toast.LENGTH_LONG).show();
2724f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            }
2725f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor
2726f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // Attach all the pictures/videos off of the UI thread.
2727f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // Show a progress alert if adding all the slides hasn't finished
2728f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // within one second.
2729f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // Stash the runnable for showing it away so we can cancel
2730f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // it later if adding completes ahead of the deadline.
2731f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            final AlertDialog dialog = new AlertDialog.Builder(ComposeMessageActivity.this)
2732f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                .setIcon(android.R.drawable.ic_dialog_alert)
2733f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                .setTitle(R.string.adding_attachments_title)
2734f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                .setMessage(R.string.adding_attachments)
2735f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                .create();
2736f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            final Runnable showProgress = new Runnable() {
2737f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                public void run() {
2738f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    dialog.show();
2739f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                }
2740f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            };
2741f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            // Schedule it for one second from now.
2742f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            mAttachmentEditorHandler.postDelayed(showProgress, 1000);
2743f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor
2744f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            final int numberToImport = importCount;
2745f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            new Thread(new Runnable() {
2746f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                public void run() {
2747f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    for (int i = 0; i < numberToImport; i++) {
2748f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                        Parcelable uri = uris.get(i);
2749f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                        addAttachment(mimeType, (Uri) uri, true);
2750f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    }
2751f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    // Cancel pending show of the progress alert if necessary.
2752f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    mAttachmentEditorHandler.removeCallbacks(showProgress);
2753f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                    dialog.dismiss();
2754f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor                }
2755f6f761abb71455f79c8cadda94aa15fc15bb6d39Tom Taylor            }).start();
275607e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick            return true;
275772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
27581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
275907e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        return false;
276072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
276172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
27629c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor    // mVideoUri will look like this: content://media/external/video/media
27639c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor    private static final String mVideoUri = Video.Media.getContentUri("external").toString();
27649c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor    // mImageUri will look like this: content://media/external/images/media
27659c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor    private static final String mImageUri = Images.Media.getContentUri("external").toString();
27669c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor
2767edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor    private void addAttachment(String type, Uri uri, boolean append) {
2768edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        if (uri != null) {
27699c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            // When we're handling Intent.ACTION_SEND_MULTIPLE, the passed in items can be
27709c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            // videos, and/or images, and/or some other unknown types we don't handle. When
27719c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            // a single attachment is "shared" the type will specify an image or video. When
27729c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            // there are multiple types, the type passed in is "*/*". In that case, we've got
27739c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            // to look at the uri to figure out if it is an image or video.
27749c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            boolean wildcard = "*/*".equals(type);
27759c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            if (type.startsWith("image/") || (wildcard && uri.toString().startsWith(mImageUri))) {
2776edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                addImage(uri, append);
27779c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor            } else if (type.startsWith("video/") ||
27789c21cccdc5737c0d54fe9220959964b0a9bdaa9dTom Taylor                    (wildcard && uri.toString().startsWith(mVideoUri))) {
2779edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor                addVideo(uri, append);
2780edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor            }
2781edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor        }
2782edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor    }
2783edd39351defc331fc268a6ed88338f64fe6f17cfTom Taylor
278472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private String getResourcesString(int id, String mediaName) {
278572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Resources r = getResources();
278672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return r.getString(id, mediaName);
278772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
27881d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2789b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private void drawBottomPanel() {
279072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Reset the counter for text editor.
279172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        resetCounter();
27921d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2793b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (mWorkingMessage.hasSlideshow()) {
2794b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mBottomPanel.setVisibility(View.GONE);
2795b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mAttachmentEditor.requestFocus();
2796b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            return;
279772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
27981d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2799b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mBottomPanel.setVisibility(View.VISIBLE);
2800c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang
2801c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang        CharSequence text = mWorkingMessage.getText();
2802c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang
2803dc58429bf08e9d5ba8c43f0ac21e7cd18ea8cb06Tom Taylor        // TextView.setTextKeepState() doesn't like null input.
2804c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang        if (text != null) {
2805c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang            mTextEditor.setTextKeepState(text);
2806c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang        } else {
2807c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang            mTextEditor.setText("");
2808c6482ba8c841c539dd67be432cbc59bb597a771fWei Huang        }
2809b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    }
2810b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
2811b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private void drawTopPanel() {
2812b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        showSubjectEditor(mWorkingMessage.hasSubject());
281372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
281472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
281572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
281672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Interface methods
281772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
281872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
281972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public void onClick(View v) {
282072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if ((v == mSendButton) && isPreparedForSending()) {
282172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            confirmSendMessageIfNeeded();
282272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
282372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
282472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
282572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
282672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (event != null) {
282749183c099b1ac79f3c2fe97368ed76caba4ca98eWei Huang            // if shift key is down, then we want to insert the '\n' char in the TextView;
282849183c099b1ac79f3c2fe97368ed76caba4ca98eWei Huang            // otherwise, the default action is to send the message.
282972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (!event.isShiftPressed()) {
283072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (isPreparedForSending()) {
283149183c099b1ac79f3c2fe97368ed76caba4ca98eWei Huang                    confirmSendMessageIfNeeded();
283272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
283372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                return true;
283472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
283572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return false;
283672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
28371d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
283872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (isPreparedForSending()) {
283972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            confirmSendMessageIfNeeded();
284072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
284172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return true;
284272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
284372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
284472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final TextWatcher mTextEditorWatcher = new TextWatcher() {
284572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
284672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
284772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
284872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onTextChanged(CharSequence s, int start, int before, int count) {
284972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // This is a workaround for bug 1609057.  Since onUserInteraction() is
285072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // not called when the user touches the soft keyboard, we pretend it was
285172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // called when textfields changes.  This should be removed when the bug
285272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // is fixed.
285372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            onUserInteraction();
285472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2855b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mWorkingMessage.setText(s);
28561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
285772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            updateSendButtonState();
285872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
285972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            updateCounter(s, start, before, count);
28604cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen
28614cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen            ensureCorrectButtonHeight();
28624cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen        }
28634cb031ac8f130f345cdfd482f8eb7bd38232c1cfChristopher Van Der Westhuizen
286472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void afterTextChanged(Editable s) {
286572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
286672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
286772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
2868b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen    /**
2869b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen     * Ensures that if the text edit box extends past two lines then the
2870b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen     * button will be shifted up to allow enough space for the character
2871b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen     * counter string to be placed beneath it.
2872b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen     */
2873b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen    private void ensureCorrectButtonHeight() {
2874b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        int currentTextLines = mTextEditor.getLineCount();
2875b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        if (currentTextLines <= 2) {
2876b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            mTextCounter.setVisibility(View.GONE);
2877b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        }
2878b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        else if (currentTextLines > 2 && mTextCounter.getVisibility() == View.GONE) {
2879b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            // Making the counter invisible ensures that it is used to correctly
2880b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            // calculate the position of the send button even if we choose not to
2881b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            // display the text.
2882b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen            mTextCounter.setVisibility(View.INVISIBLE);
2883b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        }
2884b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen    }
2885b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen
2886b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    private final TextWatcher mSubjectEditorWatcher = new TextWatcher() {
2887b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
2888b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
2889b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        public void onTextChanged(CharSequence s, int start, int before, int count) {
2890396a06af4e393f5aab3864c43392a67c60715d38Tom Taylor            mWorkingMessage.setSubject(s, true);
2891b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        }
2892b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
2893b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        public void afterTextChanged(Editable s) { }
2894b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick    };
2895b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
289672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
289772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    // Private methods
289872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    //==========================================================
289972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
290072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    /**
290172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     * Initialize all UI elements from resources.
290272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project     */
290372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void initResourceRefs() {
290472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView = (MessageListView) findViewById(R.id.history);
290572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setDivider(null);      // no divider so we look like IM conversation.
290672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mBottomPanel = findViewById(R.id.bottom_panel);
290772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextEditor = (EditText) findViewById(R.id.embedded_text_editor);
290872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextEditor.setOnEditorActionListener(this);
290972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextEditor.addTextChangedListener(mTextEditorWatcher);
291072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextCounter = (TextView) findViewById(R.id.text_counter);
291172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSendButton = (Button) findViewById(R.id.send_button);
291272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSendButton.setOnClickListener(this);
291372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTopPanel = findViewById(R.id.recipients_subject_linear);
2914b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mTopPanel.setFocusable(false);
2915b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mAttachmentEditor = (AttachmentEditor) findViewById(R.id.attachment_editor);
2916b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mAttachmentEditor.setHandler(mAttachmentEditorHandler);
291772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
291872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29193e10898d774b0005fc776865216651346503024bTom Taylor    private void confirmDeleteDialog(OnClickListener listener, boolean locked) {
292072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        AlertDialog.Builder builder = new AlertDialog.Builder(this);
29213e10898d774b0005fc776865216651346503024bTom Taylor        builder.setTitle(locked ? R.string.confirm_dialog_locked_title :
29223e10898d774b0005fc776865216651346503024bTom Taylor            R.string.confirm_dialog_title);
292372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setIcon(android.R.drawable.ic_dialog_alert);
292472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setCancelable(true);
29253e10898d774b0005fc776865216651346503024bTom Taylor        builder.setMessage(locked ? R.string.confirm_delete_locked_message :
29263e10898d774b0005fc776865216651346503024bTom Taylor                    R.string.confirm_delete_message);
29273e10898d774b0005fc776865216651346503024bTom Taylor        builder.setPositiveButton(R.string.delete, listener);
292872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.setNegativeButton(R.string.no, null);
292972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        builder.show();
293072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
293172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
293272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    void undeliveredMessageDialog(long date) {
293372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        String body;
293472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        LinearLayout dialog = (LinearLayout) LayoutInflater.from(this).inflate(
293572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                R.layout.retry_sending_dialog, null);
293672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
293772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (date >= 0) {
293872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            body = getString(R.string.undelivered_msg_dialog_body,
293972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    MessageUtils.formatTimeStampString(this, date));
294072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else {
294172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // FIXME: we can not get sms retry time.
294272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            body = getString(R.string.undelivered_sms_dialog_body);
294372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
294472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
294572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        ((TextView) dialog.findViewById(R.id.body_text_view)).setText(body);
294672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
294772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        Toast undeliveredDialog = new Toast(this);
294872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        undeliveredDialog.setView(dialog);
294972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        undeliveredDialog.setDuration(Toast.LENGTH_LONG);
295072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        undeliveredDialog.show();
295172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
295272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
295372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void startMsgListQuery() {
2954ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        Uri conversationUri = mConversation.getUri();
2955f539c6440cffefab7b4677cd6a3ee9f019317bdcWei Huang
2956ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        if (conversationUri == null) {
295772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
295872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
29591d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
296009a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
296109a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang            log("startMsgListQuery for " + conversationUri);
296209a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang        }
2963ffadc4bc7da30cf61e33092133efb37b7e483f63Wei Huang
296472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Cancel any pending queries
296572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mBackgroundQueryHandler.cancelOperation(MESSAGE_LIST_QUERY_TOKEN);
296672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        try {
296772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // Kick off the new query
296872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mBackgroundQueryHandler.startQuery(
2969ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick                    MESSAGE_LIST_QUERY_TOKEN, null, conversationUri,
297072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    PROJECTION, null, null, null);
297172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } catch (SQLiteException e) {
297272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SqliteWrapper.checkSQLiteException(this, e);
297372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
297472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
297572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
29765d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project    private void initMessageList() {
2977591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project        if (mMsgListAdapter != null) {
2978591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project            return;
2979591d17e9a51bb9f829d6860dc7aa0bad25062cd5The Android Open Source Project        }
29801d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
2981f114492537753bc68640d4a0d403861387296bcbMark Wagner        String highlightString = getIntent().getStringExtra("highlight");
2982459ad1ea05610f7c071f65da6842e00e21bd5eafMark Wagner        Pattern highlight = highlightString == null
2983459ad1ea05610f7c071f65da6842e00e21bd5eafMark Wagner            ? null
2984459ad1ea05610f7c071f65da6842e00e21bd5eafMark Wagner            : Pattern.compile("\\b" + Pattern.quote(highlightString), Pattern.CASE_INSENSITIVE);
2985331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner
298672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Initialize the list adapter with a null cursor.
2987f1ab045ff991e1ec3e4161d213627b8629971c0eTom Taylor        mMsgListAdapter = new MessageListAdapter(this, null, mMsgListView, true, highlight);
298872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListAdapter.setOnDataSetChangedListener(mDataSetChangedListener);
298972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListAdapter.setMsgListItemHandler(mMessageListItemHandler);
299072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setAdapter(mMsgListAdapter);
299172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setItemsCanFocus(false);
299272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setVisibility(View.VISIBLE);
299372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setOnCreateContextMenuListener(mMsgListMenuCreateListener);
299472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mMsgListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
299572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
29961998176d6069aa9c3e3f2f16e66f12073554ec66Tom Taylor                if (view != null) {
29971998176d6069aa9c3e3f2f16e66f12073554ec66Tom Taylor                    ((MessageListItem) view).onMessageListItemClick();
29981998176d6069aa9c3e3f2f16e66f12073554ec66Tom Taylor                }
299972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
300072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        });
300172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
300272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3003cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick    private void loadDraft() {
3004b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (mWorkingMessage.isWorthSaving()) {
3005b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            Log.w(TAG, "loadDraft() called with non-empty working message");
300607e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick            return;
300707e7775d5a792334b89436bf5479bfd5abeeb8c4Ficus Kirkpatrick        }
3008b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick
3009812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
3010812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            log("loadDraft: call WorkingMessage.loadDraft");
3011812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
3012812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3013ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mWorkingMessage = WorkingMessage.loadDraft(this, mConversation);
3014cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick    }
30151d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3016cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick    private void saveDraft() {
3017b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // TODO: Do something better here.  Maybe make discard() legal
3018b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // to call twice and make isEmpty() return true if discarded
3019b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // so it is caught in the clause above this one?
3020b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (mWorkingMessage.isDiscarded()) {
302186bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick            return;
302286bcfc0a48ee7baf6a9221711bce071a2b7f3cafFicus Kirkpatrick        }
30231d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3024b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (!mWaitingForSubActivity && !mWorkingMessage.isWorthSaving()) {
3025812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
3026812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang                log("saveDraft: not worth saving, discard WorkingMessage and bail");
3027812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            }
3028b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            mWorkingMessage.discard();
3029cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick            return;
3030cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        }
3031812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3032812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
3033812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            log("saveDraft: call WorkingMessage.saveDraft");
3034812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
3035812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3036b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage.saveDraft();
30371d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3038b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        if (mToastForDraftSave) {
3039cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick            Toast.makeText(this, R.string.message_saved_as_draft,
3040cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick                    Toast.LENGTH_SHORT).show();
3041cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick        }
3042cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick    }
3043cd87a4285599aeb732e4590136a5c103e1c42ccdFicus Kirkpatrick
304472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private boolean isPreparedForSending() {
304507fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        int recipientCount = recipientCount();
304607fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
304707fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        return recipientCount > 0 && recipientCount <= MmsConfig.getRecipientLimit() &&
304807fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            (mWorkingMessage.hasAttachment() || mWorkingMessage.hasText());
304907fd438290f18696092b00813ff1c57ac16fa81cTom Taylor    }
305007fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
305107fd438290f18696092b00813ff1c57ac16fa81cTom Taylor    private int recipientCount() {
305207fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        int recipientCount;
30531d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
30541d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // To avoid creating a bunch of invalid Contacts when the recipients
305507fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        // editor is in flux, we keep the recipients list empty.  So if the
30561d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // recipients editor is showing, see if there is anything in it rather
30571d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // than consulting the empty recipient list.
30581d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        if (isRecipientsEditorVisible()) {
305907fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            recipientCount = mRecipientsEditor.getRecipientCount();
30601d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        } else {
306107fd438290f18696092b00813ff1c57ac16fa81cTom Taylor            recipientCount = getRecipients().size();
30621d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        }
306307fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        return recipientCount;
306472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
306572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
30663b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng    private void sendMessage(boolean bCheckEcmMode) {
30673b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng        if (bCheckEcmMode) {
30686be18bedb5b87dbbcdb54f37d5a0945bd0f71377Tom Taylor            // TODO: expose this in telephony layer for SDK build
30693b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE);
30703b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            if (Boolean.parseBoolean(inEcm)) {
30713b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                try {
30723b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                    startActivityForResult(
30733b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                            new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS, null),
30743b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                            REQUEST_CODE_ECM_EXIT_DIALOG);
30753b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                    return;
30763b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                } catch (ActivityNotFoundException e) {
30773b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                    // continue to send message
30783b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                    Log.e(TAG, "Cannot find EmergencyCallbackModeExitDialog", e);
30793b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng                }
30803b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng            }
30813b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng        }
30823b100dd8425ea38ea70c6d29ef0d85aa85482ae5Richard Meng
3083249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao        if (!mSendingMessage) {
3084249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            // send can change the recipients. Make sure we remove the listeners first and then add
3085249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            // them back once the recipient list has settled.
3086249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            removeRecipientsListeners();
3087249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            mWorkingMessage.send();
3088249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            mSentMessage = true;
3089249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            mSendingMessage = true;
3090249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao            addRecipientsListeners();
3091249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao        }
3092b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // But bail out if we are supposed to exit after the message is sent.
30935d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        if (mExitOnSent) {
3094afb09d77dbeceb3d40d9a5a8e8bd2c0ecf9ce125Wei Huang            finish();
30955d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        }
309672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
30971d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
30982f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project    private void resetMessage() {
3099d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang        if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
3100d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang            log("resetMessage");
3101d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang        }
3102d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang
3103b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // Make the attachment editor hide its view.
3104b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mAttachmentEditor.hideView();
31051d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3106b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        // Hide the subject editor.
3107b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        showSubjectEditor(false);
31081d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
31095d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // Focus to the text editor.
31105d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        mTextEditor.requestFocus();
31115d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project
31125d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // We have to remove the text change listener while the text editor gets cleared and
31135d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // we subsequently turn the message back into SMS. When the listener is listening while
31145d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // doing the clearing, it's fighting to update its counts and itself try and turn
31155d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        // the message one way or the other.
31165d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project        mTextEditor.removeTextChangedListener(mTextEditorWatcher);
31175d2d0046ada7b53205e537d8675d32a8785e8d1dThe Android Open Source Project
31182f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        // Clear the text box.
31192f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project        TextKeyListener.clear(mTextEditor.getText());
31201d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3121b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick        mWorkingMessage = WorkingMessage.createEmpty(this);
3122ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mWorkingMessage.setConversation(mConversation);
312372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3124984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        hideRecipientEditor();
31251d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        drawBottomPanel();
31261d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
31271d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        // "Or not", in this case.
31281d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick        updateSendButtonState();
31291d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
313072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Our changes are done. Let the listener respond to text changes once again.
313172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextEditor.addTextChangedListener(mTextEditorWatcher);
31321d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
313372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // Close the soft on-screen keyboard if we're in landscape mode so the user can see the
313472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // conversation.
313572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mIsLandscape) {
31361d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick            InputMethodManager inputMethodManager =
313772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
31381d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
313972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            inputMethodManager.hideSoftInputFromWindow(mTextEditor.getWindowToken(), 0);
314072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
314107fd438290f18696092b00813ff1c57ac16fa81cTom Taylor
314207fd438290f18696092b00813ff1c57ac16fa81cTom Taylor        mLastRecipientCount = 0;
3143249ae2eeecf2dd7fe15ef3e050cac57042c7468eBai Tao        mSendingMessage = false;
314472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project   }
314572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
314672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void updateSendButtonState() {
314772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        boolean enable = false;
314872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (isPreparedForSending()) {
314972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // When the type of attachment is slideshow, we should
315072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // also hide the 'Send' button since the slideshow view
315172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            // already has a 'Send' button embedded.
3152b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            if (!mWorkingMessage.hasSlideshow()) {
315372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                enable = true;
315472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            } else {
315572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                mAttachmentEditor.setCanSend(true);
315672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
315772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        } else if (null != mAttachmentEditor){
315872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mAttachmentEditor.setCanSend(false);
315972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
316072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3161b89a6e906aee77fb2c575a166e1fb6b521327276Christopher Van Der Westhuizen        setSendButtonText(mWorkingMessage.requiresMms());
316272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSendButton.setEnabled(enable);
316372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSendButton.setFocusable(enable);
316472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
316572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
316672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private long getMessageDate(Uri uri) {
316772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (uri != null) {
316872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            Cursor cursor = SqliteWrapper.query(this, mContentResolver,
316972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    uri, new String[] { Mms.DATE }, null, null, null);
317072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            if (cursor != null) {
317172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                try {
317272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if ((cursor.getCount() == 1) && cursor.moveToFirst()) {
317372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return cursor.getLong(0) * 1000L;
317472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
317572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                } finally {
317672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    cursor.close();
317772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
317872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
317972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
318072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        return NO_DATE_FOR_DIALOG;
318172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
318272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3183ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick    private void initActivityState(Bundle bundle, Intent intent) {
3184ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        if (bundle != null) {
3185ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            String recipients = bundle.getString("recipients");
318656e77a576e452f26da6941f01746435fe4b3011bWei Huang            mConversation = Conversation.get(this,
318756e77a576e452f26da6941f01746435fe4b3011bWei Huang                    ContactList.getByNumbers(recipients,
3188e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                            false /* don't block */, true /* replace number */), false);
3189e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor            addRecipientsListeners();
3190ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            mExitOnSent = bundle.getBoolean("exit_on_sent", false);
3191ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            mWorkingMessage.readStateFromBundle(bundle);
3192ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            return;
3193ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        }
31941d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3195ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        // If we have been passed a thread_id, use that to find our
3196ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        // conversation.
3197ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        long threadId = intent.getLongExtra("thread_id", 0);
3198ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        if (threadId > 0) {
3199e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor            mConversation = Conversation.get(this, threadId, false);
3200ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        } else {
320159be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang            Uri intentData = intent.getData();
320259be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang
320359be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang            if (intentData != null) {
320459be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                // try to get a conversation based on the data URI passed to our intent.
320509a75ac1d3710e60dbe78ead3dee6863ffb380caWei Huang                mConversation = Conversation.get(this, intentData, false);
320659be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang            } else {
320759be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                // special intent extra parameter to specify the address
320859be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                String address = intent.getStringExtra("address");
320959be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                if (!TextUtils.isEmpty(address)) {
321056e77a576e452f26da6941f01746435fe4b3011bWei Huang                    mConversation = Conversation.get(this, ContactList.getByNumbers(address,
3211e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                            false /* don't block */, true /* replace number */), false);
321259be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                } else {
321359be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                    mConversation = Conversation.createNew(this);
321459be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang                }
321559be3105fb43b5e9fcb363981dfa3de31c1bc2a8Wei Huang            }
321672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
3217e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor        addRecipientsListeners();
3218ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick
3219ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mExitOnSent = intent.getBooleanExtra("exit_on_sent", false);
3220ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick        mWorkingMessage.setText(intent.getStringExtra("sms_body"));
3221396a06af4e393f5aab3864c43392a67c60715d38Tom Taylor        mWorkingMessage.setSubject(intent.getStringExtra("subject"), false);
322272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
322372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
322472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void initFocus() {
322572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (!mIsKeyboardOpen) {
322672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
322772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
322872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
322972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If the recipients editor is visible, there is nothing in it,
323072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // and the text editor is not already focused, focus the
323172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // recipients editor.
3232984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang        if (isRecipientsEditorVisible()
3233984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang                && TextUtils.isEmpty(mRecipientsEditor.getText())
3234984577aa5f27608f2d251130ce373ca722d6ffe5Wei Huang                && !mTextEditor.isFocused()) {
323572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mRecipientsEditor.requestFocus();
323672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            return;
323772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
323872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
323972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        // If we decided not to focus the recipients editor, focus the text editor.
324072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mTextEditor.requestFocus();
324172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
324272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
324372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final MessageListAdapter.OnDataSetChangedListener
324472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mDataSetChangedListener = new MessageListAdapter.OnDataSetChangedListener() {
324572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public void onDataSetChanged(MessageListAdapter adapter) {
324672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPossiblePendingNotification = true;
324772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
324867b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor
324967b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor        public void onContentChanged(MessageListAdapter adapter) {
325067b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor            startMsgListQuery();
325167b794480aaad0e1958df2988671b78ea03b76e1Tom Taylor        }
325272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    };
325372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
325472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void checkPendingNotification() {
325572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mPossiblePendingNotification && hasWindowFocus()) {
3256ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick            mConversation.markAsRead();
325772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mPossiblePendingNotification = false;
325872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
325972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
326072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
326172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private final class BackgroundQueryHandler extends AsyncQueryHandler {
326272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        public BackgroundQueryHandler(ContentResolver contentResolver) {
326372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            super(contentResolver);
326472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
326572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
326672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
326772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
326872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch(token) {
326972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                case MESSAGE_LIST_QUERY_TOKEN:
3270331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    int newSelectionPos = -1;
3271331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    long targetMsgId = getIntent().getLongExtra("select_id", -1);
3272331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    if (targetMsgId != -1) {
3273331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                        cursor.moveToPosition(-1);
3274331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                        while (cursor.moveToNext()) {
3275331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                            long msgId = cursor.getLong(COLUMN_ID);
3276331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                            if (msgId == targetMsgId) {
3277331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                                newSelectionPos = cursor.getPosition();
3278331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                                break;
3279331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                            }
3280331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                        }
3281331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    }
3282331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner
32832f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    mMsgListAdapter.changeCursor(cursor);
3284331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    if (newSelectionPos != -1) {
3285331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                        mMsgListView.setSelection(newSelectionPos);
3286331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner                    }
32871d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
32882f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // Once we have completed the query for the message history, if
32892f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // there is nothing in the cursor and we are not composing a new
3290d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                    // message, we must be editing a draft in a new conversation (unless
3291d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                    // mSentMessage is true).
32922f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // Show the recipients editor to give the user a chance to add
32932f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // more people before the conversation begins.
3294d9db0a031dc9116d13bf55c8476f8daa910a9804Wei Huang                    if (cursor.getCount() == 0 && !isRecipientsEditorVisible() && !mSentMessage) {
32952f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                        initRecipientsEditor();
32962f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    }
329772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
32982f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // FIXME: freshing layout changes the focused view to an unexpected
32992f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    // one, set it back to TextEditor forcely.
33002f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                    mTextEditor.requestFocus();
330172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3302436042159134e8ecbc57097340a5bd81f2912574Tom Taylor                    mConversation.blockMarkAsRead(false);
330372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return;
33043e10898d774b0005fc776865216651346503024bTom Taylor
33053e10898d774b0005fc776865216651346503024bTom Taylor                case ConversationList.HAVE_LOCKED_MESSAGES_TOKEN:
33063e10898d774b0005fc776865216651346503024bTom Taylor                    long threadId = (Long)cookie;
33073e10898d774b0005fc776865216651346503024bTom Taylor                    ConversationList.confirmDeleteThreadDialog(
33083e10898d774b0005fc776865216651346503024bTom Taylor                            new ConversationList.DeleteThreadListener(threadId,
33093e10898d774b0005fc776865216651346503024bTom Taylor                                mBackgroundQueryHandler, ComposeMessageActivity.this),
33103e10898d774b0005fc776865216651346503024bTom Taylor                            threadId == -1,
33113e10898d774b0005fc776865216651346503024bTom Taylor                            cursor != null && cursor.getCount() > 0,
33123e10898d774b0005fc776865216651346503024bTom Taylor                            ComposeMessageActivity.this);
33133e10898d774b0005fc776865216651346503024bTom Taylor                    break;
331472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
331572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
331672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
331772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        @Override
331872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        protected void onDeleteComplete(int token, Object cookie, int result) {
331972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            switch(token) {
332072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            case DELETE_MESSAGE_TOKEN:
33213e10898d774b0005fc776865216651346503024bTom Taylor            case ConversationList.DELETE_CONVERSATION_TOKEN:
332272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Update the notification for new messages since they
332372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // may be deleted.
33243b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor                MessagingNotification.nonBlockingUpdateNewMessageIndicator(
33253b21f6ab04db5936d73e9f53032f1587389380ffTom Taylor                        ComposeMessageActivity.this, false, false);
332672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // Update the notification for failed messages since they
332772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // may be deleted.
33282f56791329cefc49ce79663b8d3aff50594cc1f3The Android Open Source Project                updateSendFailedNotification();
332972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                break;
333072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
333172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
3332b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            // If we're deleting the whole conversation, throw away
3333b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick            // our current working message and bail.
33343e10898d774b0005fc776865216651346503024bTom Taylor            if (token == ConversationList.DELETE_CONVERSATION_TOKEN) {
3335b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                mWorkingMessage.discard();
3336976506f3ecfce6c9a0dd6f3e5c8d9f2ed9feae03Satish Roddom                Conversation.init(ComposeMessageActivity.this);
3337b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick                finish();
333872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
333972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
334072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
334172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
334272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    private void showSmileyDialog() {
334372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        if (mSmileyDialog == null) {
334472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            int[] icons = SmileyParser.DEFAULT_SMILEY_RES_IDS;
334572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            String[] names = getResources().getStringArray(
334672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmileyParser.DEFAULT_SMILEY_NAMES);
334772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final String[] texts = getResources().getStringArray(
334872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    SmileyParser.DEFAULT_SMILEY_TEXTS);
334972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
335072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final int N = names.length;
335172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
335272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            List<Map<String, ?>> entries = new ArrayList<Map<String, ?>>();
335372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            for (int i = 0; i < N; i++) {
335472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // We might have different ASCII for the same icon, skip it if
335572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                // the icon is already added.
335672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                boolean added = false;
335772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                for (int j = 0; j < i; j++) {
335872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (icons[i] == icons[j]) {
335972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        added = true;
336072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        break;
336172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
336272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
336372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                if (!added) {
336472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    HashMap<String, Object> entry = new HashMap<String, Object>();
336572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
336672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    entry. put("icon", icons[i]);
336772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    entry. put("name", names[i]);
336872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    entry.put("text", texts[i]);
336972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
337072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    entries.add(entry);
337172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
337272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            }
337372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
337472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            final SimpleAdapter a = new SimpleAdapter(
337572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    this,
337672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    entries,
337772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    R.layout.smiley_menu_item,
337872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    new String[] {"icon", "name", "text"},
337972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    new int[] {R.id.smiley_icon, R.id.smiley_name, R.id.smiley_text});
338072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            SimpleAdapter.ViewBinder viewBinder = new SimpleAdapter.ViewBinder() {
338172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                public boolean setViewValue(View view, Object data, String textRepresentation) {
338272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    if (view instanceof ImageView) {
338372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        Drawable img = getResources().getDrawable((Integer)data);
338472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        ((ImageView)view).setImageDrawable(img);
338572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                        return true;
338672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    }
338772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    return false;
338872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
338972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            };
339072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            a.setViewBinder(viewBinder);
339172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
339272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            AlertDialog.Builder b = new AlertDialog.Builder(this);
339372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
339472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            b.setTitle(getString(R.string.menu_insert_smiley));
339572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
339672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            b.setCancelable(true);
339772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            b.setAdapter(a, new DialogInterface.OnClickListener() {
3398ab6141d9c98f1a6024fac52fe3c897076d8549c0Ficus Kirkpatrick                @SuppressWarnings("unchecked")
339972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                public final void onClick(DialogInterface dialog, int which) {
340072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    HashMap<String, Object> item = (HashMap<String, Object>) a.getItem(which);
340172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                    mTextEditor.append((String)item.get("text"));
3402f96423bc61528310b3db01930883d25e66866b99Tom Taylor
3403f96423bc61528310b3db01930883d25e66866b99Tom Taylor                    dialog.dismiss();
340472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project                }
340572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            });
340672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
340772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project            mSmileyDialog = b.create();
340872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        }
340972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project
341072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project        mSmileyDialog.show();
341172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project    }
34121d98ae0b203e01034ddead4214d1520ce863a23bFicus Kirkpatrick
3413458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    public void onUpdate(final Contact updated) {
3414458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor        // Using an existing handler for the post, rather than conjuring up a new one.
3415458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor        mMessageListItemHandler.post(new Runnable() {
3416458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor            public void run() {
3417e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                ContactList recipients = isRecipientsEditorVisible() ?
3418e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                        mRecipientsEditor.constructContactsFromInput() : getRecipients();
3419d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
3420d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                    log("[CMA] onUpdate contact updated: " + updated);
3421e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                    log("[CMA] onUpdate recipients: " + recipients);
3422d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                }
34238b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner                updateTitle(recipients);
342436991889eac09f621b14ffd5a7a47317a35870a3Tom Taylor
3425d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                // The contact information for one (or more) of the recipients has changed.
3426d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                // Rebuild the message list so each MessageItem will get the last contact info.
3427d2edbbb15b418002e3c6542e092a8228ad39baafTom Taylor                ComposeMessageActivity.this.mMsgListAdapter.notifyDataSetChanged();
3428e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor
3429e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                if (mRecipientsEditor != null) {
3430e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                    mRecipientsEditor.populate(recipients);
3431e692b9dcf5742e7a3ef3a7e64b44bb9d08f05b57Tom Taylor                }
3432458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor            }
3433458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor        });
3434458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    }
343528433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
3436458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    private void addRecipientsListeners() {
3437ea5e915b6104ff0e30c313bcb5a96f838997e57bMark Wagner        Contact.addListener(this);
3438458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    }
343928433bd3a11e22e8ec9383053b74a7eb6454b463Tom Taylor
3440458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    private void removeRecipientsListeners() {
3441ea5e915b6104ff0e30c313bcb5a96f838997e57bMark Wagner        Contact.removeListener(this);
3442458dea8d1858e418b6918f477d0139335b14ff45Tom Taylor    }
3443812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3444812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang    public static Intent createIntent(Context context, long threadId) {
34450af188b645e0fa69f5f5b8bff14b11c117535d8cTom Taylor        Intent intent = new Intent(context, ComposeMessageActivity.class);
3446812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3447812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        if (threadId > 0) {
3448812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang            intent.setData(Conversation.getUri(threadId));
3449812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        }
3450812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang
3451812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang        return intent;
3452812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang   }
345372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project}
3454