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 20331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport java.util.Map; 21f114492537753bc68640d4a0d403861387296bcbMark Wagnerimport java.util.regex.Matcher; 22f114492537753bc68640d4a0d403861387296bcbMark Wagnerimport java.util.regex.Pattern; 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.app.AlertDialog; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.DialogInterface; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Intent; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Bitmap; 2951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylorimport android.graphics.Paint.FontMetricsInt; 3072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.Typeface; 3172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.graphics.drawable.Drawable; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.net.Uri; 3372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Handler; 3472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.os.Message; 354f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylorimport android.provider.ContactsContract.Profile; 36f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport android.provider.Telephony.Sms; 3772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.telephony.PhoneNumberUtils; 385c113729220385c970b9e941b93a162054285209Tom Taylorimport android.telephony.TelephonyManager; 397c8748972faf3078f53ef9ecbe6c95f0903f43f7satokimport android.text.Html; 4072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.SpannableStringBuilder; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.TextUtils; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.method.HideReturnsTransformationMethod; 4372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.ForegroundColorSpan; 448b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagnerimport android.text.style.LineHeightSpan; 4572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.StyleSpan; 468b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagnerimport android.text.style.TextAppearanceSpan; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.text.style.URLSpan; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.AttributeSet; 495a3151adedd991252dd529c75e85a3374970dfb0Tom Taylorimport android.util.Log; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.view.View.OnClickListener; 5251e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylorimport android.view.ViewGroup; 5372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ArrayAdapter; 5472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.Button; 5572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ImageButton; 5672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.ImageView; 5772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.LinearLayout; 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.widget.TextView; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60bb8edcae15a50b3651261db70791afc668aae294Tom Taylorimport com.android.mms.MmsApp; 61331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.R; 62313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylorimport com.android.mms.data.Contact; 63331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.data.WorkingMessage; 6451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylorimport com.android.mms.model.SlideModel; 6551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylorimport com.android.mms.model.SlideshowModel; 66331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.transaction.Transaction; 67331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.transaction.TransactionBundle; 68331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.transaction.TransactionService; 69331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagnerimport com.android.mms.util.DownloadManager; 7051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylorimport com.android.mms.util.ItemLoadedCallback; 7179bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylorimport com.android.mms.util.ThumbnailManager.ImageLoaded; 72f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.ContentType; 73f7e8281a223af6228e6399055a6197a1edd9bc3aTom Taylorimport com.google.android.mms.pdu.PduHeaders; 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/** 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * This class provides view of a message in the messages list. 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class MessageListItem extends LinearLayout implements 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project SlideViewInterface, OnClickListener { 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final String EXTRA_URLS = "com.android.mms.ExtraUrls"; 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String TAG = "MessageListItem"; 8351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor private static final boolean DEBUG = false; 84f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor private static final boolean DEBUG_DONT_LOAD_IMAGES = false; 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 863efec5a219021385d816639f5c801c4cd277ae9dTom Taylor static final int MSG_LIST_EDIT = 1; 873efec5a219021385d816639f5c801c4cd277ae9dTom Taylor static final int MSG_LIST_PLAY = 2; 883efec5a219021385d816639f5c801c4cd277ae9dTom Taylor static final int MSG_LIST_DETAILS = 3; 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private View mMmsView; 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ImageView mImageView; 925a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private ImageView mLockedIndicator; 935a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private ImageView mDeliveredIndicator; 945a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor private ImageView mDetailsIndicator; 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private ImageButton mSlideShowButton; 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private TextView mBodyTextView; 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Button mDownloadButton; 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private TextView mDownloadingLabel; 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private Handler mHandler; 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private MessageItem mMessageItem; 1014759133e3c935e751815bf4f997d029caa64d889Bai Tao private String mDefaultCountryIso; 1023fb271abe0c478d0ea8432830589774182079c86Tom Taylor private TextView mDateView; 10310ca1d3969305df50fb07a17f5d23b0ed59f7868Tom Taylor public View mMessageBlock; 10410ca1d3969305df50fb07a17f5d23b0ed59f7868Tom Taylor private QuickContactDivot mAvatar; 105313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor static private Drawable sDefaultContactImage; 10651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor private Presenter mPresenter; 107eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor private int mPosition; // for debugging 108721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor private ImageLoadedCallback mImageLoadedCallback; 109c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor private boolean mMultiRecipients; 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public MessageListItem(Context context) { 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(context); 1134759133e3c935e751815bf4f997d029caa64d889Bai Tao mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso(); 114313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor 115313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor if (sDefaultContactImage == null) { 116313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor sDefaultContactImage = context.getResources().getDrawable(R.drawable.ic_contact_picture); 117313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public MessageListItem(Context context, AttributeSet attrs) { 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super(context, attrs); 1228b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 1238b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner int color = mContext.getResources().getColor(R.color.timestamp_color); 1248b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner mColorSpan = new ForegroundColorSpan(color); 125d019225935f492f67dc189d9199bb61eeb7f02d5Tom Taylor mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso(); 126313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor 127313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor if (sDefaultContactImage == null) { 128313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor sDefaultContactImage = context.getResources().getDrawable(R.drawable.ic_contact_picture); 129313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project @Override 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected void onFinishInflate() { 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project super.onFinishInflate(); 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mBodyTextView = (TextView) findViewById(R.id.text_view); 1373fb271abe0c478d0ea8432830589774182079c86Tom Taylor mDateView = (TextView) findViewById(R.id.date_view); 1385a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mLockedIndicator = (ImageView) findViewById(R.id.locked_indicator); 1395a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator = (ImageView) findViewById(R.id.delivered_indicator); 1405a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDetailsIndicator = (ImageView) findViewById(R.id.details_indicator); 14110ca1d3969305df50fb07a17f5d23b0ed59f7868Tom Taylor mAvatar = (QuickContactDivot) findViewById(R.id.avatar); 14210ca1d3969305df50fb07a17f5d23b0ed59f7868Tom Taylor mMessageBlock = findViewById(R.id.message_block); 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 145c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor public void bind(MessageItem msgItem, boolean convHasMultiRecipients, int position) { 1460fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor if (DEBUG) { 1470fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor Log.v(TAG, "bind for item: " + position + " old: " + 1480fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor (mMessageItem != null ? mMessageItem.toString() : "NULL" ) + 1490fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor " new " + msgItem.toString()); 1500fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor } 1510fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor boolean sameItem = mMessageItem != null && mMessageItem.mMsgId == msgItem.mMsgId; 15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMessageItem = msgItem; 153ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor 154eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor mPosition = position; 155c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor mMultiRecipients = convHasMultiRecipients; 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project setLongClickable(false); 1589549e0f231f524440c6a9112fe07ac898f82c88aTom Taylor setClickable(false); // let the list view handle clicks on the item normally. When 1599549e0f231f524440c6a9112fe07ac898f82c88aTom Taylor // clickable is true, clicks bypass the listview and go straight 1609549e0f231f524440c6a9112fe07ac898f82c88aTom Taylor // to this listitem. We always want the listview to handle the 1619549e0f231f524440c6a9112fe07ac898f82c88aTom Taylor // clicks first. 16272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msgItem.mMessageType) { 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND: 16551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor bindNotifInd(); 16672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 16772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 1680fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor bindCommonMessage(sameItem); 16972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 17072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 17272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1739a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev public void unbind() { 1749a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev // Clear all references to the message item, which can contain attachments and other 1759a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev // memory-intensive objects 1769a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev if (mImageView != null) { 1779a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev // Because #setOnClickListener may have set the listener to an object that has the 1789a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev // message item in its closure. 1799a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev mImageView.setOnClickListener(null); 1809a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev } 1819a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev if (mSlideShowButton != null) { 1829a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev // Because #drawPlaybackButton sets the tag to mMessageItem 1839a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev mSlideShowButton.setTag(null); 1849a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev } 18551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor // leave the presenter in case it's needed when rebound to a different MessageItem. 18651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (mPresenter != null) { 18751e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mPresenter.cancelBackgroundLoading(); 18851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 1899a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev } 1909a0457146d9caa476ca8c44c950dce741ede8143Todor Kalaydjiev 19172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public MessageItem getMessageItem() { 19272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return mMessageItem; 19372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 194331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 19572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setMsgListItemHandler(Handler handler) { 19672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mHandler = handler; 19772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 198331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 19951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor private void bindNotifInd() { 200f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor showMmsView(false); 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String msgSizeText = mContext.getString(R.string.message_size_label) 20351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor + String.valueOf((mMessageItem.mMessageSize + 1023) / 1024) 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + mContext.getString(R.string.kilobyte); 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 206c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor mBodyTextView.setText(formatMessage(mMessageItem, null, 20751e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mSubject, 20851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mHighlight, 20951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mTextContentType)); 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 211c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor mDateView.setText(buildTimestampLine(msgSizeText + " " + mMessageItem.mTimestamp)); 2123fb271abe0c478d0ea8432830589774182079c86Tom Taylor 213ac2f043e7ded55ce835d474e578155ecc0c79668Tom Taylor switch (mMessageItem.getMmsDownloadStatus()) { 2149dd9f0f2049d48dea799b5f2fe8a54380ee5b748Roger Chen case DownloadManager.STATE_PRE_DOWNLOADING: 21572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DownloadManager.STATE_DOWNLOADING: 2165c113729220385c970b9e941b93a162054285209Tom Taylor showDownloadingAttachment(); 21772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 2185c113729220385c970b9e941b93a162054285209Tom Taylor case DownloadManager.STATE_UNKNOWN: 21972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DownloadManager.STATE_UNSTARTED: 2205c113729220385c970b9e941b93a162054285209Tom Taylor DownloadManager downloadManager = DownloadManager.getInstance(); 2215c113729220385c970b9e941b93a162054285209Tom Taylor boolean autoDownload = downloadManager.isAuto(); 2225c113729220385c970b9e941b93a162054285209Tom Taylor boolean dataSuspended = (MmsApp.getApplication().getTelephonyManager() 2235c113729220385c970b9e941b93a162054285209Tom Taylor .getDataState() == TelephonyManager.DATA_SUSPENDED); 2245c113729220385c970b9e941b93a162054285209Tom Taylor 2255c113729220385c970b9e941b93a162054285209Tom Taylor // If we're going to automatically start downloading the mms attachment, then 2265c113729220385c970b9e941b93a162054285209Tom Taylor // don't bother showing the download button for an instant before the actual 2275c113729220385c970b9e941b93a162054285209Tom Taylor // download begins. Instead, show downloading as taking place. 2285c113729220385c970b9e941b93a162054285209Tom Taylor if (autoDownload && !dataSuspended) { 2295c113729220385c970b9e941b93a162054285209Tom Taylor showDownloadingAttachment(); 2305c113729220385c970b9e941b93a162054285209Tom Taylor break; 2315c113729220385c970b9e941b93a162054285209Tom Taylor } 23272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DownloadManager.STATE_TRANSIENT_FAILURE: 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case DownloadManager.STATE_PERMANENT_FAILURE: 23472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 23572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project setLongClickable(true); 23672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project inflateDownloadControls(); 23772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadingLabel.setVisibility(View.GONE); 23872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadButton.setVisibility(View.VISIBLE); 23972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadButton.setOnClickListener(new OnClickListener() { 24044e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 24172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onClick(View v) { 24272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadingLabel.setVisibility(View.VISIBLE); 24372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadButton.setVisibility(View.GONE); 24472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Intent intent = new Intent(mContext, TransactionService.class); 24551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor intent.putExtra(TransactionBundle.URI, mMessageItem.mMessageUri.toString()); 24672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project intent.putExtra(TransactionBundle.TRANSACTION_TYPE, 24772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Transaction.RETRIEVE_TRANSACTION); 24872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mContext.startService(intent); 2499dd9f0f2049d48dea799b5f2fe8a54380ee5b748Roger Chen 2509dd9f0f2049d48dea799b5f2fe8a54380ee5b748Roger Chen DownloadManager.getInstance().markState( 2519dd9f0f2049d48dea799b5f2fe8a54380ee5b748Roger Chen mMessageItem.mMessageUri, DownloadManager.STATE_PRE_DOWNLOADING); 25272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }); 25472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 25572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 25672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2575a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor // Hide the indicators. 2585a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mLockedIndicator.setVisibility(View.GONE); 2595a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator.setVisibility(View.GONE); 2605a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDetailsIndicator.setVisibility(View.GONE); 26151e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor updateAvatarView(mMessageItem.mAddress, false); 26272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 264c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor private String buildTimestampLine(String timestamp) { 2659c9df2773645d195dbf17df91d7cccdf5154fe84Tom Taylor if (!mMultiRecipients || mMessageItem.isMe() || TextUtils.isEmpty(mMessageItem.mContact)) { 266c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor // Never show "Me" for messages I sent. 267c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor return timestamp; 268c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor } 269c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor // This is a group conversation, show the sender's name on the same line as the timestamp. 270c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor return mContext.getString(R.string.message_timestamp_format, mMessageItem.mContact, 271c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor timestamp); 272c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor } 273c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor 2745c113729220385c970b9e941b93a162054285209Tom Taylor private void showDownloadingAttachment() { 2755c113729220385c970b9e941b93a162054285209Tom Taylor inflateDownloadControls(); 2765c113729220385c970b9e941b93a162054285209Tom Taylor mDownloadingLabel.setVisibility(View.VISIBLE); 2775c113729220385c970b9e941b93a162054285209Tom Taylor mDownloadButton.setVisibility(View.GONE); 2785c113729220385c970b9e941b93a162054285209Tom Taylor } 2795c113729220385c970b9e941b93a162054285209Tom Taylor 2804f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor private void updateAvatarView(String addr, boolean isSelf) { 281313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor Drawable avatarDrawable; 2824f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor if (isSelf || !TextUtils.isEmpty(addr)) { 2834f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor Contact contact = isSelf ? Contact.getMe(false) : Contact.get(addr, false); 284313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor avatarDrawable = contact.getAvatar(mContext, sDefaultContactImage); 285313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor 2864f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor if (isSelf) { 2874f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor mAvatar.assignContactUri(Profile.CONTENT_URI); 288313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } else { 2894f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor if (contact.existsInDatabase()) { 2904f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor mAvatar.assignContactUri(contact.getUri()); 2914f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor } else { 2924f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor mAvatar.assignContactFromPhone(contact.getNumber(), true); 2934f1871e8e85598c94d5f09d508c690c41fdcce16Tom Taylor } 294313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } 295313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } else { 296313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor avatarDrawable = sDefaultContactImage; 297313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } 298313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor mAvatar.setImageDrawable(avatarDrawable); 299313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor } 300313d09ee558e6ac94ab28a205357885dc830cd0dTom Taylor 3010fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor private void bindCommonMessage(final boolean sameItem) { 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mDownloadButton != null) { 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadButton.setVisibility(View.GONE); 30472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadingLabel.setVisibility(View.GONE); 30572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Since the message text should be concatenated with the sender's 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // address(or name), I have to display it here instead of 30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // displaying it by the Presenter. 30972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); 31072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 311ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor boolean haveLoadedPdu = mMessageItem.isSms() || mMessageItem.mSlideshow != null; 312ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // Here we're avoiding reseting the avatar to the empty avatar when we're rebinding 313ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // to the same item. This happens when there's a DB change which causes the message item 314ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // cache in the MessageListAdapter to get cleared. When an mms MessageItem is newly 315ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // created, it has no info in it except the message id. The info is eventually loaded 316ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // and bindCommonMessage is called again (see onPduLoaded below). When we haven't loaded 317ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // the pdu, we don't want to call updateAvatarView because it 318ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // will set the avatar to the generic avatar then when this method is called again 319ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor // from onPduLoaded, it will reset to the real avatar. This test is to avoid that flash. 320ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor if (!sameItem || haveLoadedPdu) { 3210fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor boolean isSelf = Sms.isOutgoingFolder(mMessageItem.mBoxId); 3220fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor String addr = isSelf ? null : mMessageItem.mAddress; 3230fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor updateAvatarView(addr, isSelf); 3240fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor } 3258b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 32672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Get and/or lazily set the formatted message from/on the 32772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // MessageItem. Because the MessageItem instances come from a 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // cache (currently of size ~50), the hit rate on avoiding the 32972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // expensive formatMessage() call is very high. 33051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor CharSequence formattedMessage = mMessageItem.getCachedFormattedMessage(); 33172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (formattedMessage == null) { 332c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor formattedMessage = formatMessage(mMessageItem, 33351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mBody, 33451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mSubject, 33551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mHighlight, 33651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.mTextContentType); 337a46c89868eb1cd1ec9d0b3c248c83cfab21c8203Tom Taylor mMessageItem.setCachedFormattedMessage(formattedMessage); 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 339ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor if (!sameItem || haveLoadedPdu) { 340ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor mBodyTextView.setText(formattedMessage); 341ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor } 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 34351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor // Debugging code to put the URI of the image attachment in the body of the list item. 34451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (DEBUG) { 34551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor String debugText = null; 34651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (mMessageItem.mSlideshow == null) { 34751e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor debugText = "NULL slideshow"; 34851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } else { 349c7c68dba4f3440f234f65eef579f9aaa82682f8cTom Taylor SlideModel slide = mMessageItem.mSlideshow.get(0); 35051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (slide == null) { 35151e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor debugText = "NULL first slide"; 35251e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } else if (!slide.hasImage()) { 35351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor debugText = "Not an image"; 35451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } else { 35551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor debugText = slide.getImage().getUri().toString(); 35651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 35751e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 358eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor mBodyTextView.setText(mPosition + ": " + debugText); 35951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 36051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor 3613fb271abe0c478d0ea8432830589774182079c86Tom Taylor // If we're in the process of sending a message (i.e. pending), then we show a "SENDING..." 3623fb271abe0c478d0ea8432830589774182079c86Tom Taylor // string in place of the timestamp. 363ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor if (!sameItem || haveLoadedPdu) { 364ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor mDateView.setText(buildTimestampLine(mMessageItem.isSending() ? 365ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor mContext.getResources().getString(R.string.sending_message) : 366ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor mMessageItem.mTimestamp)); 367ac5b230500508d676267f264dc4ce63ae0900937Tom Taylor } 36851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (mMessageItem.isSms()) { 369f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor showMmsView(false); 37051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageItem.setOnPduLoaded(null); 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 372eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor if (DEBUG) { 373eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor Log.v(TAG, "bindCommonMessage for item: " + mPosition + " " + 374fbcd6a7287afd459fee2521bfaf2d4f70668c85aTom Taylor mMessageItem.toString() + 3750fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor " mMessageItem.mAttachmentType: " + mMessageItem.mAttachmentType + 3760fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor " sameItem: " + sameItem); 377eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor } 378f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (mMessageItem.mAttachmentType != WorkingMessage.TEXT) { 3790fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor if (!sameItem) { 3800fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor setImage(null, null); 3810fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor } 382f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor setOnClickListener(mMessageItem); 383f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor drawPlaybackButton(mMessageItem); 384f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } else { 385f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor showMmsView(false); 386f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 387eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor if (mMessageItem.mSlideshow == null) { 388eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor mMessageItem.setOnPduLoaded(new MessageItem.PduLoadedCallback() { 389eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor public void onPduLoaded(MessageItem messageItem) { 390eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor if (DEBUG) { 391eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor Log.v(TAG, "PduLoadedCallback in MessageListItem for item: " + mPosition + 392eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor " " + (mMessageItem == null ? "NULL" : mMessageItem.toString()) + 393eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor " passed in item: " + 394eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor (messageItem == null ? "NULL" : messageItem.toString())); 395eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor } 396eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor if (messageItem != null && mMessageItem != null && 397eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor messageItem.getMessageId() == mMessageItem.getMessageId()) { 398106d27e66e192ac88eb86440c015a617f990c2a6Tom Taylor mMessageItem.setCachedFormattedMessage(null); 3990fd8d0e7ec0fc246dcdbea999920cbbe7fca61e9Tom Taylor bindCommonMessage(true); 400eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor } 401eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor } 402eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor }); 403eee73088ec62f011fe99abfc7aac1ec6fd3feb52Tom Taylor } else { 40451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (mPresenter == null) { 40551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mPresenter = PresenterFactory.getPresenter( 40651e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor "MmsThumbnailPresenter", mContext, 40751e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor this, mMessageItem.mSlideshow); 40851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } else { 40951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mPresenter.setModel(mMessageItem.mSlideshow); 41051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mPresenter.setView(this); 41151e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 412721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor if (mImageLoadedCallback == null) { 413721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor mImageLoadedCallback = new ImageLoadedCallback(this); 414721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor } else { 415721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor mImageLoadedCallback.reset(this); 416721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor } 417721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor mPresenter.present(mImageLoadedCallback); 418442a32e235a56401a849beda5564912bb2783e57Tom Taylor } 41972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor drawRightStatusIndicator(mMessageItem); 4219f756084b90d25fef7c22dfbb9d5842676164b34Kenny Root 4229f756084b90d25fef7c22dfbb9d5842676164b34Kenny Root requestLayout(); 42372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 42472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 42579bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor static private class ImageLoadedCallback implements ItemLoadedCallback<ImageLoaded> { 426721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor private long mMessageId; 42779bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor private final MessageListItem mListItem; 42851e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor 42951e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor public ImageLoadedCallback(MessageListItem listItem) { 43051e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mListItem = listItem; 43151e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor mMessageId = listItem.getMessageItem().getMessageId(); 43251e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 43351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor 434721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor public void reset(MessageListItem listItem) { 435721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor mMessageId = listItem.getMessageItem().getMessageId(); 436721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor } 437721ad07121cb9b0cd76bdbbc88494aa8f4d45a6dTom Taylor 43879bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor public void onItemLoaded(ImageLoaded imageLoaded, Throwable exception) { 439f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (DEBUG_DONT_LOAD_IMAGES) { 440f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor return; 441f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 44251e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor // Make sure we're still pointing to the same message. The list item could have 44351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor // been recycled. 44451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor MessageItem msgItem = mListItem.mMessageItem; 44551e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor if (msgItem != null && msgItem.getMessageId() == mMessageId) { 44679bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor if (imageLoaded.mIsVideo) { 44779bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor mListItem.setVideoThumbnail(null, imageLoaded.mBitmap); 44879bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor } else { 44979bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor mListItem.setImage(null, imageLoaded.mBitmap); 45079bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor } 45151e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 45251e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 45351e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor } 45451e4621fa12400b1e79cc18b7bb0f9a83af6b622Tom Taylor 45544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 45672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void startAudio() { 45772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 45872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 45972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46044e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 46172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void startVideo() { 46272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 46372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 46544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 46672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setAudio(Uri audio, String name, Map<String, ?> extras) { 46772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 46872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 46972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 47044e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 47172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setImage(String name, Bitmap bitmap) { 472f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor showMmsView(true); 47372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 4745a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor try { 4755a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor mImageView.setImageBitmap(bitmap); 4765a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor mImageView.setVisibility(VISIBLE); 4775a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor } catch (java.lang.OutOfMemoryError e) { 4785a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor Log.e(TAG, "setImage: out of memory: ", e); 4796f53960f9a27fe76ba11735ede0778456d3f6930Tom Taylor } 48072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 48172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 482f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor private void showMmsView(boolean visible) { 48372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mMmsView == null) { 48472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mMmsView = findViewById(R.id.mms_view); 485f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor // if mMmsView is still null here, that mean the mms section hasn't been inflated 486f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor 487f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (visible && mMmsView == null) { 488f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor //inflate the mms view_stub 489f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor View mmsStub = findViewById(R.id.mms_layout_view_stub); 490f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mmsStub.setVisibility(View.VISIBLE); 491f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mMmsView = findViewById(R.id.mms_view); 492f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 493f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 494f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (mMmsView != null) { 495f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (mImageView == null) { 496f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mImageView = (ImageView) findViewById(R.id.image_view); 497f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 498f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor if (mSlideShowButton == null) { 499f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mSlideShowButton = (ImageButton) findViewById(R.id.play_slideshow_button); 500f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor } 501f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mMmsView.setVisibility(visible ? View.VISIBLE : View.GONE); 502f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor mImageView.setVisibility(visible ? View.VISIBLE : View.GONE); 50372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 50472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 505331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 50672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void inflateDownloadControls() { 50772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (mDownloadButton == null) { 50872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project //inflate the download controls 50972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project findViewById(R.id.mms_downloading_view_stub).setVisibility(VISIBLE); 51072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadButton = (Button) findViewById(R.id.btn_download_msg); 51172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mDownloadingLabel = (TextView) findViewById(R.id.label_downloading); 51272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 51472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5158b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 5168b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner private LineHeightSpan mSpan = new LineHeightSpan() { 51744e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 5188b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner public void chooseHeight(CharSequence text, int start, 5198b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner int end, int spanstartv, int v, FontMetricsInt fm) { 5208b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner fm.ascent -= 10; 5218b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner } 5228b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner }; 5238b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 5248b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner TextAppearanceSpan mTextSmallSpan = 5258b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner new TextAppearanceSpan(mContext, android.R.style.TextAppearance_Small); 5268b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 5278b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner ForegroundColorSpan mColorSpan = null; // set in ctor 5288b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 529c1f03822994dc09939060c41e0ce9cb37175b054Tom Taylor private CharSequence formatMessage(MessageItem msgItem, String body, 5303fb271abe0c478d0ea8432830589774182079c86Tom Taylor String subject, Pattern highlight, 5315a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor String contentType) { 5323fb271abe0c478d0ea8432830589774182079c86Tom Taylor SpannableStringBuilder buf = new SpannableStringBuilder(); 53372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project boolean hasSubject = !TextUtils.isEmpty(subject); 53572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (hasSubject) { 536c7c68dba4f3440f234f65eef579f9aaa82682f8cTom Taylor buf.append(mContext.getResources().getString(R.string.inline_subject, subject)); 53772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 53872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 53972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (!TextUtils.isEmpty(body)) { 5407c8748972faf3078f53ef9ecbe6c95f0903f43f7satok // Converts html to spannable if ContentType is "text/html". 5417c8748972faf3078f53ef9ecbe6c95f0903f43f7satok if (contentType != null && ContentType.TEXT_HTML.equals(contentType)) { 5427c8748972faf3078f53ef9ecbe6c95f0903f43f7satok buf.append("\n"); 5437c8748972faf3078f53ef9ecbe6c95f0903f43f7satok buf.append(Html.fromHtml(body)); 5447c8748972faf3078f53ef9ecbe6c95f0903f43f7satok } else { 5457c8748972faf3078f53ef9ecbe6c95f0903f43f7satok if (hasSubject) { 5467c8748972faf3078f53ef9ecbe6c95f0903f43f7satok buf.append(" - "); 5477c8748972faf3078f53ef9ecbe6c95f0903f43f7satok } 548c7c68dba4f3440f234f65eef579f9aaa82682f8cTom Taylor buf.append(body); 54972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 55072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 5518b5ea2314049354f289925d4d8c6f11d13626a34Mark Wagner 552331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner if (highlight != null) { 553f114492537753bc68640d4a0d403861387296bcbMark Wagner Matcher m = highlight.matcher(buf.toString()); 554f114492537753bc68640d4a0d403861387296bcbMark Wagner while (m.find()) { 555f114492537753bc68640d4a0d403861387296bcbMark Wagner buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0); 556331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner } 557331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner } 55872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return buf; 55972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 56072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 56172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void drawPlaybackButton(MessageItem msgItem) { 56272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch (msgItem.mAttachmentType) { 563b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick case WorkingMessage.SLIDESHOW: 564b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick case WorkingMessage.AUDIO: 565b9bcfdd226bbb6f5b265f925343375192963d58aFicus Kirkpatrick case WorkingMessage.VIDEO: 56672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Show the 'Play' button and bind message info on it. 56772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSlideShowButton.setTag(msgItem); 56872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set call-back for the 'Play' button. 56972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSlideShowButton.setOnClickListener(this); 57072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSlideShowButton.setVisibility(View.VISIBLE); 57172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project setLongClickable(true); 572b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor 573b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor // When we show the mSlideShowButton, this list item's onItemClickListener doesn't 574b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor // get called. (It gets set in ComposeMessageActivity: 575b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor // mMsgListView.setOnItemClickListener) Here we explicitly set the item's 576b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor // onClickListener. It allows the item to respond to embedded html links and at the 577b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor // same time, allows the slide show play button to work. 578b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor setOnClickListener(new OnClickListener() { 57944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 580b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor public void onClick(View v) { 581b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor onMessageListItemClick(); 582b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor } 583b0ef2b0d0974c13e98055d8ffd85bef559fe80a4Tom Taylor }); 58472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 58572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 58672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project mSlideShowButton.setVisibility(View.GONE); 58772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 58872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 58972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 59072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 59172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // OnClick Listener for the playback button 59244e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 59372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onClick(View v) { 594661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor sendMessage(mMessageItem, MSG_LIST_PLAY); 595661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor } 596661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor 597661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor private void sendMessage(MessageItem messageItem, int message) { 598661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor if (mHandler != null) { 599661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor Message msg = Message.obtain(mHandler, message); 600661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor msg.obj = messageItem; 601661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor msg.sendToTarget(); // See ComposeMessageActivity.mMessageListItemHandler.handleMessage 60272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 60472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 60572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void onMessageListItemClick() { 60644e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev // If the message is a failed one, clicking it should reload it in the compose view, 60744e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev // regardless of whether it has links in it 60844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev if (mMessageItem != null && 60944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev mMessageItem.isOutgoingMessage() && 61044e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev mMessageItem.isFailedMessage() ) { 611661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor 612661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor // Assuming the current message is a failed one, reload it into the compose view so 613661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor // the user can resend it. 614661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor sendMessage(mMessageItem, MSG_LIST_EDIT); 61544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev return; 61644e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev } 61744e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev 61844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev // Check for links. If none, do nothing; if 1, open it; if >1, ask user to pick one 619b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor final URLSpan[] spans = mBodyTextView.getUrls(); 62072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 62172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (spans.length == 0) { 6223efec5a219021385d816639f5c801c4cd277ae9dTom Taylor sendMessage(mMessageItem, MSG_LIST_DETAILS); // show the message details dialog 62372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else if (spans.length == 1) { 624b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor spans[0].onClick(mBodyTextView); 62572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 626b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor ArrayAdapter<URLSpan> adapter = 627b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor new ArrayAdapter<URLSpan>(mContext, android.R.layout.select_dialog_item, spans) { 62844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 62972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public View getView(int position, View convertView, ViewGroup parent) { 63072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project View v = super.getView(position, convertView, parent); 63172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 632b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor URLSpan span = getItem(position); 633b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor String url = span.getURL(); 634b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor Uri uri = Uri.parse(url); 63572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project TextView tv = (TextView) v; 636b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor Drawable d = mContext.getPackageManager().getActivityIcon( 637b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor new Intent(Intent.ACTION_VIEW, uri)); 63872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (d != null) { 63972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project d.setBounds(0, 0, d.getIntrinsicHeight(), d.getIntrinsicHeight()); 64072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project tv.setCompoundDrawablePadding(10); 64172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project tv.setCompoundDrawables(d, null, null, null); 64272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 64372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project final String telPrefix = "tel:"; 64472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (url.startsWith(telPrefix)) { 645e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude if ((mDefaultCountryIso == null) || mDefaultCountryIso.isEmpty()) { 646e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude url = url.substring(telPrefix.length()); 647e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude } 648e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude else { 649e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude url = PhoneNumberUtils.formatNumber( 650e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude url.substring(telPrefix.length()), mDefaultCountryIso); 651e753c800a1533ee7e4f8bc3843991269f1295ec0Emmanuel Delaude } 65272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project tv.setText(url); 65472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (android.content.pm.PackageManager.NameNotFoundException ex) { 65544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev // it's ok if we're unable to set the drawable for this view - the user 65644e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev // can still use it 65772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 65872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return v; 65972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 66072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 66172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project AlertDialog.Builder b = new AlertDialog.Builder(mContext); 66372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 66472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() { 66544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 66672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public final void onClick(DialogInterface dialog, int which) { 66772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (which >= 0) { 668b4ef5fdc458756bc259806a39c3379108fe804e0Tom Taylor spans[which].onClick(mBodyTextView); 66972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 670c4a34a0ccd414e2bba937e8abd105a0383afff35Tom Taylor dialog.dismiss(); 67172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 67272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }; 673331864544ec51ba6807fc5471cc6d537b7fef198Mark Wagner 67472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project b.setTitle(R.string.select_link_title); 67572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project b.setCancelable(true); 67672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project b.setAdapter(adapter, click); 67772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 67872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 67944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 68072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public final void onClick(DialogInterface dialog, int which) { 68172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project dialog.dismiss(); 68272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project }); 68472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 68572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project b.show(); 68672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 68872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 68972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void setOnClickListener(final MessageItem msgItem) { 69072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch(msgItem.mAttachmentType) { 691661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor case WorkingMessage.IMAGE: 692661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor case WorkingMessage.VIDEO: 693661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor mImageView.setOnClickListener(new OnClickListener() { 694661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor @Override 695661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor public void onClick(View v) { 696661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor sendMessage(msgItem, MSG_LIST_PLAY); 697661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor } 698661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor }); 699661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor mImageView.setOnLongClickListener(new OnLongClickListener() { 700661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor @Override 701661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor public boolean onLongClick(View v) { 702661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor return v.showContextMenu(); 703661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor } 704661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor }); 705661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor break; 70672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 707661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor default: 708661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor mImageView.setOnClickListener(null); 709661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor break; 710661957caeb3110ae3328a995edd467ceedc07a36Tom Taylor } 71172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 71272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 71372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private void drawRightStatusIndicator(MessageItem msgItem) { 7145a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor // Locked icon 7155a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor if (msgItem.mLocked) { 7165a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mLockedIndicator.setImageResource(R.drawable.ic_lock_message_sms); 7175a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mLockedIndicator.setVisibility(View.VISIBLE); 7185a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } else { 7195a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mLockedIndicator.setVisibility(View.GONE); 7205a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } 7215a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 72221a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // Delivery icon - we can show a failed icon for both sms and mms, but for an actual 72321a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // delivery, we only show the icon for sms. We don't have the information here in mms to 72421a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // know whether the message has been delivered. For mms, msgItem.mDeliveryStatus set 72521a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // to MessageItem.DeliveryStatus.RECEIVED simply means the setting requesting a 72621a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // delivery report was turned on when the message was sent. Yes, it's confusing! 72744e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev if ((msgItem.isOutgoingMessage() && msgItem.isFailedMessage()) || 72844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.FAILED) { 7295ad68bd0767ac325cf272317c5eb80d08fc2b018Tom Taylor mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed); 7305a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator.setVisibility(View.VISIBLE); 73121a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor } else if (msgItem.isSms() && 73221a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED) { 7335a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator.setImageResource(R.drawable.ic_sms_mms_delivered); 7345a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator.setVisibility(View.VISIBLE); 7355a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } else { 7365a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDeliveredIndicator.setVisibility(View.GONE); 7375a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor } 7385a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor 73921a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // Message details icon - this icon is shown both for sms and mms messages. For mms, 74021a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // we show the icon if the read report or delivery report setting was set when the 74121a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // message was sent. Showing the icon tells the user there's more information 74221a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor // by selecting the "View report" menu. 74321a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.INFO || msgItem.mReadReport 74421a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor || (msgItem.isMms() && 74521a30a301e99a15217f02fddcbacfc2aa622fc7bTom Taylor msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED)) { 7465a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDetailsIndicator.setImageResource(R.drawable.ic_sms_mms_details); 7475a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDetailsIndicator.setVisibility(View.VISIBLE); 74872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } else { 7495a73318ac906b37eb5634a6975a8a26ef5ed36efTom Taylor mDetailsIndicator.setVisibility(View.GONE); 75072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75344e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 75472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setImageRegionFit(String fit) { 75572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 75672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 75772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 75844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 75972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setImageVisibility(boolean visible) { 76072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 76172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 76344e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 76472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setText(String name, String text) { 76572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 76672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 76772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 76844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 76972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setTextVisibility(boolean visible) { 77072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 77172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 77272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 77344e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 77479bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor public void setVideo(String name, Uri uri) { 77579bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor } 77679bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor 77779bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor @Override 77879bf6f70c54d08dc9c3481b8461a3a46a3cefb83Tom Taylor public void setVideoThumbnail(String name, Bitmap bitmap) { 779f627528d5e7780baa20975c067637126c3fc0f57Tom Taylor showMmsView(true); 7805a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor 7815a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor try { 7825a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor mImageView.setImageBitmap(bitmap); 7835a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor mImageView.setVisibility(VISIBLE); 7845a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor } catch (java.lang.OutOfMemoryError e) { 7855a3151adedd991252dd529c75e85a3374970dfb0Tom Taylor Log.e(TAG, "setVideo: out of memory: ", e); 78672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 78772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 78872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 78944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 79072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setVideoVisibility(boolean visible) { 79172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 79272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 79444e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 79572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void stopAudio() { 79672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 79772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 79872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 79944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 80072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void stopVideo() { 80172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 80272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 80372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 80444e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 80572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void reset() { 80672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 80772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 80844e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 80972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void setVisibility(boolean visible) { 81072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 81172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 81344e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 81472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void pauseAudio() { 81572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 81672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 81772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 81872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 81944e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 82072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void pauseVideo() { 82172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 82272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 82372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 82472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 82544e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 82672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void seekAudio(int seekTo) { 82772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 82872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 82972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 83144e86cc021e0656602ecdb6afa38051cfebea68dTodor Kalaydjiev @Override 83272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public void seekVideo(int seekTo) { 83372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Auto-generated method stub 83472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 83572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 83672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 837