Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2008 Esmertec AG.
      3  * Copyright (C) 2008 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.ui;
     19 
     20 import java.util.Map;
     21 import java.util.regex.Matcher;
     22 import java.util.regex.Pattern;
     23 
     24 import android.app.AlertDialog;
     25 import android.content.Context;
     26 import android.content.DialogInterface;
     27 import android.content.Intent;
     28 import android.graphics.Bitmap;
     29 import android.graphics.BitmapFactory;
     30 import android.graphics.Canvas;
     31 import android.graphics.Paint;
     32 import android.graphics.Typeface;
     33 import android.graphics.Paint.FontMetricsInt;
     34 import android.graphics.drawable.Drawable;
     35 import android.net.Uri;
     36 import android.os.Handler;
     37 import android.os.Message;
     38 import android.provider.Browser;
     39 import android.provider.Telephony.Mms;
     40 import android.provider.Telephony.MmsSms;
     41 import android.provider.Telephony.Sms;
     42 import android.telephony.PhoneNumberUtils;
     43 import android.telephony.TelephonyManager;
     44 import android.text.Html;
     45 import android.text.Layout;
     46 import android.text.Spannable;
     47 import android.text.SpannableStringBuilder;
     48 import android.text.TextUtils;
     49 import android.text.method.HideReturnsTransformationMethod;
     50 import android.text.style.ForegroundColorSpan;
     51 import android.text.style.LeadingMarginSpan;
     52 import android.text.style.LineHeightSpan;
     53 import android.text.style.StyleSpan;
     54 import android.text.style.TextAppearanceSpan;
     55 import android.text.style.URLSpan;
     56 import android.util.AttributeSet;
     57 import android.view.View;
     58 import android.view.ViewGroup;
     59 import android.view.View.OnClickListener;
     60 import android.widget.ArrayAdapter;
     61 import android.widget.Button;
     62 import android.widget.ImageButton;
     63 import android.widget.ImageView;
     64 import android.widget.LinearLayout;
     65 import android.widget.QuickContactBadge;
     66 import android.widget.TextView;
     67 
     68 import com.android.mms.MmsApp;
     69 import com.android.mms.R;
     70 import com.android.mms.data.WorkingMessage;
     71 import com.android.mms.transaction.Transaction;
     72 import com.android.mms.transaction.TransactionBundle;
     73 import com.android.mms.transaction.TransactionService;
     74 import com.android.mms.util.DownloadManager;
     75 import com.android.mms.util.SmileyParser;
     76 import com.google.android.mms.ContentType;
     77 import com.google.android.mms.pdu.PduHeaders;
     78 
     79 /**
     80  * This class provides view of a message in the messages list.
     81  */
     82 public class MessageListItem extends LinearLayout implements
     83         SlideViewInterface, OnClickListener {
     84     public static final String EXTRA_URLS = "com.android.mms.ExtraUrls";
     85 
     86     private static final String TAG = "MessageListItem";
     87     private static final StyleSpan STYLE_BOLD = new StyleSpan(Typeface.BOLD);
     88 
     89     static final int MSG_LIST_EDIT_MMS   = 1;
     90     static final int MSG_LIST_EDIT_SMS   = 2;
     91 
     92     private View mMsgListItem;
     93     private View mMmsView;
     94     private ImageView mImageView;
     95     private ImageView mLockedIndicator;
     96     private ImageView mDeliveredIndicator;
     97     private ImageView mDetailsIndicator;
     98     private ImageButton mSlideShowButton;
     99     private TextView mBodyTextView;
    100     private Button mDownloadButton;
    101     private TextView mDownloadingLabel;
    102     private QuickContactBadge mAvatar;
    103     private Handler mHandler;
    104     private MessageItem mMessageItem;
    105 
    106     public MessageListItem(Context context) {
    107         super(context);
    108     }
    109 
    110     public MessageListItem(Context context, AttributeSet attrs) {
    111         super(context, attrs);
    112 
    113         int color = mContext.getResources().getColor(R.color.timestamp_color);
    114         mColorSpan = new ForegroundColorSpan(color);
    115     }
    116 
    117     @Override
    118     protected void onFinishInflate() {
    119         super.onFinishInflate();
    120 
    121         mMsgListItem = findViewById(R.id.msg_list_item);
    122         mBodyTextView = (TextView) findViewById(R.id.text_view);
    123         mLockedIndicator = (ImageView) findViewById(R.id.locked_indicator);
    124         mDeliveredIndicator = (ImageView) findViewById(R.id.delivered_indicator);
    125         mDetailsIndicator = (ImageView) findViewById(R.id.details_indicator);
    126         mAvatar = (QuickContactBadge) findViewById(R.id.avatar);
    127 
    128         ViewGroup.MarginLayoutParams badgeParams = (MarginLayoutParams)mAvatar.getLayoutParams();
    129         final int badgeWidth = badgeParams.width + badgeParams.rightMargin + badgeParams.leftMargin;
    130 
    131         int lineHeight = mBodyTextView.getLineHeight();
    132         int effectiveBadgeHeight = badgeParams.height + badgeParams.topMargin - mBodyTextView.getPaddingTop();
    133         final int indentLineCount = (int) ((effectiveBadgeHeight-1) / lineHeight) + 1;
    134 
    135         mLeadingMarginSpan = new LeadingMarginSpan.LeadingMarginSpan2() {
    136             public void drawLeadingMargin(Canvas c, Paint p, int x, int dir,
    137                     int top, int baseline, int bottom, CharSequence text,
    138                     int start, int end, boolean first, Layout layout) {
    139                 // no op
    140             }
    141 
    142             public int getLeadingMargin(boolean first) {
    143                 return first ? badgeWidth : 0;
    144             }
    145 
    146             public int getLeadingMarginLineCount() {
    147                 return indentLineCount;
    148             }
    149         };
    150 
    151     }
    152 
    153     public void bind(MessageListAdapter.AvatarCache avatarCache, MessageItem msgItem) {
    154         mMessageItem = msgItem;
    155 
    156         setLongClickable(false);
    157 
    158         switch (msgItem.mMessageType) {
    159             case PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND:
    160                 bindNotifInd(msgItem);
    161                 break;
    162             default:
    163                 bindCommonMessage(avatarCache, msgItem);
    164                 break;
    165         }
    166     }
    167 
    168     public MessageItem getMessageItem() {
    169         return mMessageItem;
    170     }
    171 
    172     public void setMsgListItemHandler(Handler handler) {
    173         mHandler = handler;
    174     }
    175 
    176     private void bindNotifInd(final MessageItem msgItem) {
    177         hideMmsViewIfNeeded();
    178 
    179         String msgSizeText = mContext.getString(R.string.message_size_label)
    180                                 + String.valueOf((msgItem.mMessageSize + 1023) / 1024)
    181                                 + mContext.getString(R.string.kilobyte);
    182 
    183         mBodyTextView.setText(formatMessage(msgItem, msgItem.mContact, null, msgItem.mSubject,
    184                                             msgSizeText + "\n" + msgItem.mTimestamp,
    185                                             msgItem.mHighlight, msgItem.mTextContentType));
    186 
    187         int state = DownloadManager.getInstance().getState(msgItem.mMessageUri);
    188         switch (state) {
    189             case DownloadManager.STATE_DOWNLOADING:
    190                 inflateDownloadControls();
    191                 mDownloadingLabel.setVisibility(View.VISIBLE);
    192                 mDownloadButton.setVisibility(View.GONE);
    193                 break;
    194             case DownloadManager.STATE_UNSTARTED:
    195             case DownloadManager.STATE_TRANSIENT_FAILURE:
    196             case DownloadManager.STATE_PERMANENT_FAILURE:
    197             default:
    198                 setLongClickable(true);
    199                 inflateDownloadControls();
    200                 mDownloadingLabel.setVisibility(View.GONE);
    201                 mDownloadButton.setVisibility(View.VISIBLE);
    202                 mDownloadButton.setOnClickListener(new OnClickListener() {
    203                     public void onClick(View v) {
    204                         mDownloadingLabel.setVisibility(View.VISIBLE);
    205                         mDownloadButton.setVisibility(View.GONE);
    206                         Intent intent = new Intent(mContext, TransactionService.class);
    207                         intent.putExtra(TransactionBundle.URI, msgItem.mMessageUri.toString());
    208                         intent.putExtra(TransactionBundle.TRANSACTION_TYPE,
    209                                 Transaction.RETRIEVE_TRANSACTION);
    210                         mContext.startService(intent);
    211                     }
    212                 });
    213                 break;
    214         }
    215 
    216         // Hide the indicators.
    217         mLockedIndicator.setVisibility(View.GONE);
    218         mDeliveredIndicator.setVisibility(View.GONE);
    219         mDetailsIndicator.setVisibility(View.GONE);
    220 
    221         drawLeftStatusIndicator(msgItem.mBoxId);
    222     }
    223 
    224     private void bindCommonMessage(final MessageListAdapter.AvatarCache avatarCache, final MessageItem msgItem) {
    225         if (mDownloadButton != null) {
    226             mDownloadButton.setVisibility(View.GONE);
    227             mDownloadingLabel.setVisibility(View.GONE);
    228         }
    229         // Since the message text should be concatenated with the sender's
    230         // address(or name), I have to display it here instead of
    231         // displaying it by the Presenter.
    232         mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());
    233 
    234         String addr = null;
    235         if (!Sms.isOutgoingFolder(msgItem.mBoxId)) {
    236             addr = msgItem.mAddress;
    237         } else {
    238             addr = MmsApp.getApplication().getTelephonyManager().getLine1Number();
    239         }
    240         if (!TextUtils.isEmpty(addr)) {
    241             MessageListAdapter.AvatarCache.ContactData contactData = avatarCache.get(addr);
    242             mAvatar.setImageDrawable(contactData.getAvatar());
    243             Uri contactUri = contactData.getContactUri();
    244             // Since we load the contact info in the background, on the first screenfull of
    245             // messages, it's likely we haven't loaded the contact URI info yet. In that case,
    246             // fall back and use the phone number.
    247             if (contactUri != null) {
    248                 mAvatar.assignContactUri(contactUri);
    249             } else {
    250                 mAvatar.assignContactFromPhone(addr, true);
    251             }
    252         } else {
    253             mAvatar.setImageDrawable(null);
    254             mAvatar.assignContactUri(null);
    255         }
    256 
    257         // Get and/or lazily set the formatted message from/on the
    258         // MessageItem.  Because the MessageItem instances come from a
    259         // cache (currently of size ~50), the hit rate on avoiding the
    260         // expensive formatMessage() call is very high.
    261         CharSequence formattedMessage = msgItem.getCachedFormattedMessage();
    262         if (formattedMessage == null) {
    263             formattedMessage = formatMessage(msgItem, msgItem.mContact, msgItem.mBody,
    264                                              msgItem.mSubject, msgItem.mTimestamp,
    265                                              msgItem.mHighlight, msgItem.mTextContentType);
    266         }
    267         mBodyTextView.setText(formattedMessage);
    268 
    269         if (msgItem.isSms()) {
    270             hideMmsViewIfNeeded();
    271         } else {
    272             Presenter presenter = PresenterFactory.getPresenter(
    273                     "MmsThumbnailPresenter", mContext,
    274                     this, msgItem.mSlideshow);
    275             presenter.present();
    276 
    277             if (msgItem.mAttachmentType != WorkingMessage.TEXT) {
    278                 inflateMmsView();
    279                 mMmsView.setVisibility(View.VISIBLE);
    280                 setOnClickListener(msgItem);
    281                 drawPlaybackButton(msgItem);
    282             } else {
    283                 hideMmsViewIfNeeded();
    284             }
    285         }
    286 
    287         drawLeftStatusIndicator(msgItem.mBoxId);
    288         drawRightStatusIndicator(msgItem);
    289 
    290         requestLayout();
    291     }
    292 
    293     private void hideMmsViewIfNeeded() {
    294         if (mMmsView != null) {
    295             mMmsView.setVisibility(View.GONE);
    296         }
    297     }
    298 
    299     public void startAudio() {
    300         // TODO Auto-generated method stub
    301     }
    302 
    303     public void startVideo() {
    304         // TODO Auto-generated method stub
    305     }
    306 
    307     public void setAudio(Uri audio, String name, Map<String, ?> extras) {
    308         // TODO Auto-generated method stub
    309     }
    310 
    311     public void setImage(String name, Bitmap bitmap) {
    312         inflateMmsView();
    313 
    314         if (null == bitmap) {
    315             bitmap = BitmapFactory.decodeResource(getResources(),
    316                     R.drawable.ic_missing_thumbnail_picture);
    317         }
    318         mImageView.setImageBitmap(bitmap);
    319         mImageView.setVisibility(VISIBLE);
    320     }
    321 
    322     private void inflateMmsView() {
    323         if (mMmsView == null) {
    324             //inflate the surrounding view_stub
    325             findViewById(R.id.mms_layout_view_stub).setVisibility(VISIBLE);
    326 
    327             mMmsView = findViewById(R.id.mms_view);
    328             mImageView = (ImageView) findViewById(R.id.image_view);
    329             mSlideShowButton = (ImageButton) findViewById(R.id.play_slideshow_button);
    330         }
    331     }
    332 
    333     private void inflateDownloadControls() {
    334         if (mDownloadButton == null) {
    335             //inflate the download controls
    336             findViewById(R.id.mms_downloading_view_stub).setVisibility(VISIBLE);
    337             mDownloadButton = (Button) findViewById(R.id.btn_download_msg);
    338             mDownloadingLabel = (TextView) findViewById(R.id.label_downloading);
    339         }
    340     }
    341 
    342     private LeadingMarginSpan mLeadingMarginSpan;
    343 
    344     private LineHeightSpan mSpan = new LineHeightSpan() {
    345         public void chooseHeight(CharSequence text, int start,
    346                 int end, int spanstartv, int v, FontMetricsInt fm) {
    347             fm.ascent -= 10;
    348         }
    349     };
    350 
    351     TextAppearanceSpan mTextSmallSpan =
    352         new TextAppearanceSpan(mContext, android.R.style.TextAppearance_Small);
    353 
    354     ForegroundColorSpan mColorSpan = null;  // set in ctor
    355 
    356     private CharSequence formatMessage(MessageItem msgItem, String contact, String body,
    357                                        String subject, String timestamp, Pattern highlight,
    358                                        String contentType) {
    359         CharSequence template = mContext.getResources().getText(R.string.name_colon);
    360         SpannableStringBuilder buf =
    361             new SpannableStringBuilder(TextUtils.replace(template,
    362                 new String[] { "%s" },
    363                 new CharSequence[] { contact }));
    364 
    365         boolean hasSubject = !TextUtils.isEmpty(subject);
    366         if (hasSubject) {
    367             buf.append(mContext.getResources().getString(R.string.inline_subject, subject));
    368         }
    369 
    370         if (!TextUtils.isEmpty(body)) {
    371             // Converts html to spannable if ContentType is "text/html".
    372             if (contentType != null && ContentType.TEXT_HTML.equals(contentType)) {
    373                 buf.append("\n");
    374                 buf.append(Html.fromHtml(body));
    375             } else {
    376                 if (hasSubject) {
    377                     buf.append(" - ");
    378                 }
    379                 SmileyParser parser = SmileyParser.getInstance();
    380                 buf.append(parser.addSmileySpans(body));
    381             }
    382         }
    383         // If we're in the process of sending a message (i.e. pending), then we show a "Sending..."
    384         // string in place of the timestamp.
    385         if (msgItem.isSending()) {
    386             timestamp = mContext.getResources().getString(R.string.sending_message);
    387         }
    388         // We always show two lines because the optional icon bottoms are aligned with the
    389         // bottom of the text field, assuming there are two lines for the message and the sent time.
    390         buf.append("\n");
    391         int startOffset = buf.length();
    392 
    393         startOffset = buf.length();
    394         buf.append(TextUtils.isEmpty(timestamp) ? " " : timestamp);
    395 
    396         buf.setSpan(mTextSmallSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    397         buf.setSpan(mSpan, startOffset+1, buf.length(), 0);
    398 
    399         // Make the timestamp text not as dark
    400         buf.setSpan(mColorSpan, startOffset, buf.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
    401 
    402         if (highlight != null) {
    403             Matcher m = highlight.matcher(buf.toString());
    404             while (m.find()) {
    405                 buf.setSpan(new StyleSpan(Typeface.BOLD), m.start(), m.end(), 0);
    406             }
    407         }
    408         buf.setSpan(mLeadingMarginSpan, 0, buf.length(), 0);
    409         return buf;
    410     }
    411 
    412     private void drawPlaybackButton(MessageItem msgItem) {
    413         switch (msgItem.mAttachmentType) {
    414             case WorkingMessage.SLIDESHOW:
    415             case WorkingMessage.AUDIO:
    416             case WorkingMessage.VIDEO:
    417                 // Show the 'Play' button and bind message info on it.
    418                 mSlideShowButton.setTag(msgItem);
    419                 // Set call-back for the 'Play' button.
    420                 mSlideShowButton.setOnClickListener(this);
    421                 mSlideShowButton.setVisibility(View.VISIBLE);
    422                 setLongClickable(true);
    423 
    424                 // When we show the mSlideShowButton, this list item's onItemClickListener doesn't
    425                 // get called. (It gets set in ComposeMessageActivity:
    426                 // mMsgListView.setOnItemClickListener) Here we explicitly set the item's
    427                 // onClickListener. It allows the item to respond to embedded html links and at the
    428                 // same time, allows the slide show play button to work.
    429                 setOnClickListener(new OnClickListener() {
    430                     public void onClick(View v) {
    431                         onMessageListItemClick();
    432                     }
    433                 });
    434                 break;
    435             default:
    436                 mSlideShowButton.setVisibility(View.GONE);
    437                 break;
    438         }
    439     }
    440 
    441     // OnClick Listener for the playback button
    442     public void onClick(View v) {
    443         MessageItem mi = (MessageItem) v.getTag();
    444         switch (mi.mAttachmentType) {
    445             case WorkingMessage.VIDEO:
    446             case WorkingMessage.AUDIO:
    447             case WorkingMessage.SLIDESHOW:
    448                 MessageUtils.viewMmsMessageAttachment(mContext, mi.mMessageUri, mi.mSlideshow);
    449                 break;
    450         }
    451     }
    452 
    453     public void onMessageListItemClick() {
    454         URLSpan[] spans = mBodyTextView.getUrls();
    455 
    456         if (spans.length == 0) {
    457             // Do nothing.
    458         } else if (spans.length == 1) {
    459             Uri uri = Uri.parse(spans[0].getURL());
    460             Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    461             intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
    462             intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    463             mContext.startActivity(intent);
    464         } else {
    465             final java.util.ArrayList<String> urls = MessageUtils.extractUris(spans);
    466 
    467             ArrayAdapter<String> adapter =
    468                 new ArrayAdapter<String>(mContext, android.R.layout.select_dialog_item, urls) {
    469                 public View getView(int position, View convertView, ViewGroup parent) {
    470                     View v = super.getView(position, convertView, parent);
    471                     try {
    472                         String url = getItem(position).toString();
    473                         TextView tv = (TextView) v;
    474                         Drawable d = mContext.getPackageManager().getActivityIcon(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
    475                         if (d != null) {
    476                             d.setBounds(0, 0, d.getIntrinsicHeight(), d.getIntrinsicHeight());
    477                             tv.setCompoundDrawablePadding(10);
    478                             tv.setCompoundDrawables(d, null, null, null);
    479                         }
    480                         final String telPrefix = "tel:";
    481                         if (url.startsWith(telPrefix)) {
    482                             url = PhoneNumberUtils.formatNumber(url.substring(telPrefix.length()));
    483                         }
    484                         tv.setText(url);
    485                     } catch (android.content.pm.PackageManager.NameNotFoundException ex) {
    486                         ;
    487                     }
    488                     return v;
    489                 }
    490             };
    491 
    492             AlertDialog.Builder b = new AlertDialog.Builder(mContext);
    493 
    494             DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {
    495                 public final void onClick(DialogInterface dialog, int which) {
    496                     if (which >= 0) {
    497                         Uri uri = Uri.parse(urls.get(which));
    498                         Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    499                         intent.putExtra(Browser.EXTRA_APPLICATION_ID, mContext.getPackageName());
    500                         intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
    501                         mContext.startActivity(intent);
    502                     }
    503                 }
    504             };
    505 
    506             b.setTitle(R.string.select_link_title);
    507             b.setCancelable(true);
    508             b.setAdapter(adapter, click);
    509 
    510             b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
    511                 public final void onClick(DialogInterface dialog, int which) {
    512                     dialog.dismiss();
    513                 }
    514             });
    515 
    516             b.show();
    517         }
    518     }
    519 
    520 
    521     private void setOnClickListener(final MessageItem msgItem) {
    522         switch(msgItem.mAttachmentType) {
    523         case WorkingMessage.IMAGE:
    524         case WorkingMessage.VIDEO:
    525             mImageView.setOnClickListener(new OnClickListener() {
    526                 public void onClick(View v) {
    527                     MessageUtils.viewMmsMessageAttachment(mContext, null, msgItem.mSlideshow);
    528                 }
    529             });
    530             mImageView.setOnLongClickListener(new OnLongClickListener() {
    531                 public boolean onLongClick(View v) {
    532                     return v.showContextMenu();
    533                 }
    534             });
    535             break;
    536 
    537         default:
    538             mImageView.setOnClickListener(null);
    539             break;
    540         }
    541     }
    542 
    543     private void drawLeftStatusIndicator(int msgBoxId) {
    544         switch (msgBoxId) {
    545             case Mms.MESSAGE_BOX_INBOX:
    546                 mMsgListItem.setBackgroundResource(R.drawable.listitem_background_lightblue);
    547                 break;
    548 
    549             case Mms.MESSAGE_BOX_DRAFTS:
    550             case Sms.MESSAGE_TYPE_FAILED:
    551             case Sms.MESSAGE_TYPE_QUEUED:
    552             case Mms.MESSAGE_BOX_OUTBOX:
    553                 mMsgListItem.setBackgroundResource(R.drawable.listitem_background);
    554                 break;
    555 
    556             default:
    557                 mMsgListItem.setBackgroundResource(R.drawable.listitem_background);
    558                 break;
    559         }
    560     }
    561 
    562     private void setErrorIndicatorClickListener(final MessageItem msgItem) {
    563         String type = msgItem.mType;
    564         final int what;
    565         if (type.equals("sms")) {
    566             what = MSG_LIST_EDIT_SMS;
    567         } else {
    568             what = MSG_LIST_EDIT_MMS;
    569         }
    570         mDeliveredIndicator.setOnClickListener(new OnClickListener() {
    571             public void onClick(View v) {
    572                 if (null != mHandler) {
    573                     Message msg = Message.obtain(mHandler, what);
    574                     msg.obj = new Long(msgItem.mMsgId);
    575                     msg.sendToTarget();
    576                 }
    577             }
    578         });
    579     }
    580 
    581     private void drawRightStatusIndicator(MessageItem msgItem) {
    582         // Locked icon
    583         if (msgItem.mLocked) {
    584             mLockedIndicator.setImageResource(R.drawable.ic_lock_message_sms);
    585             mLockedIndicator.setVisibility(View.VISIBLE);
    586         } else {
    587             mLockedIndicator.setVisibility(View.GONE);
    588         }
    589 
    590         // Delivery icon
    591         if (msgItem.isOutgoingMessage() && msgItem.isFailedMessage()) {
    592             mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed);
    593             setErrorIndicatorClickListener(msgItem);
    594             mDeliveredIndicator.setVisibility(View.VISIBLE);
    595         } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.FAILED) {
    596             mDeliveredIndicator.setImageResource(R.drawable.ic_list_alert_sms_failed);
    597             mDeliveredIndicator.setVisibility(View.VISIBLE);
    598         } else if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.RECEIVED) {
    599             mDeliveredIndicator.setImageResource(R.drawable.ic_sms_mms_delivered);
    600             mDeliveredIndicator.setVisibility(View.VISIBLE);
    601         } else {
    602             mDeliveredIndicator.setVisibility(View.GONE);
    603         }
    604 
    605         // Message details icon
    606         if (msgItem.mDeliveryStatus == MessageItem.DeliveryStatus.INFO || msgItem.mReadReport) {
    607             mDetailsIndicator.setImageResource(R.drawable.ic_sms_mms_details);
    608             mDetailsIndicator.setVisibility(View.VISIBLE);
    609         } else {
    610             mDetailsIndicator.setVisibility(View.GONE);
    611         }
    612     }
    613 
    614     public void setImageRegionFit(String fit) {
    615         // TODO Auto-generated method stub
    616     }
    617 
    618     public void setImageVisibility(boolean visible) {
    619         // TODO Auto-generated method stub
    620     }
    621 
    622     public void setText(String name, String text) {
    623         // TODO Auto-generated method stub
    624     }
    625 
    626     public void setTextVisibility(boolean visible) {
    627         // TODO Auto-generated method stub
    628     }
    629 
    630     public void setVideo(String name, Uri video) {
    631         inflateMmsView();
    632         Bitmap bitmap = VideoAttachmentView.createVideoThumbnail(mContext, video);
    633         if (null == bitmap) {
    634             bitmap = BitmapFactory.decodeResource(getResources(),
    635                     R.drawable.ic_missing_thumbnail_video);
    636         }
    637         mImageView.setImageBitmap(bitmap);
    638         mImageView.setVisibility(VISIBLE);
    639     }
    640 
    641     public void setVideoVisibility(boolean visible) {
    642         // TODO Auto-generated method stub
    643     }
    644 
    645     public void stopAudio() {
    646         // TODO Auto-generated method stub
    647     }
    648 
    649     public void stopVideo() {
    650         // TODO Auto-generated method stub
    651     }
    652 
    653     public void reset() {
    654         if (mImageView != null) {
    655             mImageView.setVisibility(GONE);
    656         }
    657     }
    658 
    659     public void setVisibility(boolean visible) {
    660         // TODO Auto-generated method stub
    661     }
    662 
    663     public void pauseAudio() {
    664         // TODO Auto-generated method stub
    665 
    666     }
    667 
    668     public void pauseVideo() {
    669         // TODO Auto-generated method stub
    670 
    671     }
    672 
    673     public void seekAudio(int seekTo) {
    674         // TODO Auto-generated method stub
    675 
    676     }
    677 
    678     public void seekVideo(int seekTo) {
    679         // TODO Auto-generated method stub
    680 
    681     }
    682 }
    683