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