@Override
  public void setVideoThumbnail(String name, Bitmap bitmap) {
    showMmsView(true);

    try {
      mImageView.setImageBitmap(bitmap);
      mImageView.setVisibility(VISIBLE);
    } catch (java.lang.OutOfMemoryError e) {
      Log.e(TAG, "setVideo: out of memory: ", e);
    }
  }
  private void bindCommonMessage() {
    if (mDownloadButton != null) {
      mDownloadButton.setVisibility(View.GONE);
      mDownloadingLabel.setVisibility(View.GONE);
    }
    // Since the message text should be concatenated with the sender's
    // address(or name), I have to display it here instead of
    // displaying it by the Presenter.
    mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());

    boolean isSelf = Sms.isOutgoingFolder(mMessageItem.mBoxId);
    String addr = isSelf ? null : mMessageItem.mAddress;
    updateAvatarView(addr, isSelf);

    // Get and/or lazily set the formatted message from/on the
    // MessageItem.  Because the MessageItem instances come from a
    // cache (currently of size ~50), the hit rate on avoiding the
    // expensive formatMessage() call is very high.
    CharSequence formattedMessage = mMessageItem.getCachedFormattedMessage();
    if (formattedMessage == null) {
      formattedMessage =
          formatMessage(
              mMessageItem,
              mMessageItem.mContact,
              mMessageItem.mBody,
              mMessageItem.mSubject,
              mMessageItem.mHighlight,
              mMessageItem.mTextContentType);
      mMessageItem.setCachedFormattedMessage(formattedMessage);
    }
    mBodyTextView.setText(formattedMessage);

    // Debugging code to put the URI of the image attachment in the body of the list item.
    if (DEBUG) {
      String debugText = null;
      if (mMessageItem.mSlideshow == null) {
        debugText = "NULL slideshow";
      } else {
        SlideModel slide = ((SlideshowModel) mMessageItem.mSlideshow).get(0);
        if (slide == null) {
          debugText = "NULL first slide";
        } else if (!slide.hasImage()) {
          debugText = "Not an image";
        } else {
          debugText = slide.getImage().getUri().toString();
        }
      }
      mBodyTextView.setText(mPosition + ": " + debugText);
    }

    // If we're in the process of sending a message (i.e. pending), then we show a "SENDING..."
    // string in place of the timestamp.
    mDateView.setText(
        mMessageItem.isSending()
            ? mContext.getResources().getString(R.string.sending_message)
            : mMessageItem.mTimestamp);

    if (mMessageItem.isSms()) {
      showMmsView(false);
      mMessageItem.setOnPduLoaded(null);
    } else {
      if (DEBUG) {
        Log.v(
            TAG,
            "bindCommonMessage for item: "
                + mPosition
                + " "
                + mMessageItem.toString()
                + " mMessageItem.mAttachmentType: "
                + mMessageItem.mAttachmentType);
      }
      if (mMessageItem.mAttachmentType != WorkingMessage.TEXT) {
        setImage(null, null);
        setOnClickListener(mMessageItem);
        drawPlaybackButton(mMessageItem);
      } else {
        showMmsView(false);
      }
      if (mMessageItem.mSlideshow == null) {
        mMessageItem.setOnPduLoaded(
            new MessageItem.PduLoadedCallback() {
              public void onPduLoaded(MessageItem messageItem) {
                if (DEBUG) {
                  Log.v(
                      TAG,
                      "PduLoadedCallback in MessageListItem for item: "
                          + mPosition
                          + " "
                          + (mMessageItem == null ? "NULL" : mMessageItem.toString())
                          + " passed in item: "
                          + (messageItem == null ? "NULL" : messageItem.toString()));
                }
                if (messageItem != null
                    && mMessageItem != null
                    && messageItem.getMessageId() == mMessageItem.getMessageId()) {
                  mMessageItem.setCachedFormattedMessage(null);
                  bindCommonMessage();
                }
              }
            });
      } else {
        if (mPresenter == null) {
          mPresenter =
              PresenterFactory.getPresenter(
                  "MmsThumbnailPresenter", mContext, this, mMessageItem.mSlideshow);
        } else {
          mPresenter.setModel(mMessageItem.mSlideshow);
          mPresenter.setView(this);
        }
        if (mImageLoadedCallback == null) {
          mImageLoadedCallback = new ImageLoadedCallback(this);
        } else {
          mImageLoadedCallback.reset(this);
        }
        mPresenter.present(mImageLoadedCallback);
      }
    }
    drawRightStatusIndicator(mMessageItem);

    requestLayout();
  }
  private void bindNotifInd() {
    showMmsView(false);

    String msgSizeText =
        mContext.getString(R.string.message_size_label)
            + String.valueOf((mMessageItem.mMessageSize + 1023) / 1024)
            + mContext.getString(R.string.kilobyte);

    mBodyTextView.setText(
        formatMessage(
            mMessageItem,
            mMessageItem.mContact,
            null,
            mMessageItem.mSubject,
            mMessageItem.mHighlight,
            mMessageItem.mTextContentType));

    mDateView.setText(msgSizeText + " " + mMessageItem.mTimestamp);

    switch (mMessageItem.getMmsDownloadStatus()) {
      case DownloadManager.STATE_DOWNLOADING:
        showDownloadingAttachment();
        break;
      case DownloadManager.STATE_UNKNOWN:
      case DownloadManager.STATE_UNSTARTED:
        DownloadManager downloadManager = DownloadManager.getInstance();
        boolean autoDownload = downloadManager.isAuto();
        boolean dataSuspended =
            (MmsApp.getApplication().getTelephonyManager().getDataState()
                == TelephonyManager.DATA_SUSPENDED);

        // If we're going to automatically start downloading the mms attachment, then
        // don't bother showing the download button for an instant before the actual
        // download begins. Instead, show downloading as taking place.
        if (autoDownload && !dataSuspended) {
          showDownloadingAttachment();
          break;
        }
      case DownloadManager.STATE_TRANSIENT_FAILURE:
      case DownloadManager.STATE_PERMANENT_FAILURE:
      default:
        setLongClickable(true);
        inflateDownloadControls();
        mDownloadingLabel.setVisibility(View.GONE);
        mDownloadButton.setVisibility(View.VISIBLE);
        mDownloadButton.setOnClickListener(
            new OnClickListener() {
              @Override
              public void onClick(View v) {
                mDownloadingLabel.setVisibility(View.VISIBLE);
                mDownloadButton.setVisibility(View.GONE);
                Intent intent = new Intent(mContext, TransactionService.class);
                intent.putExtra(TransactionBundle.URI, mMessageItem.mMessageUri.toString());
                intent.putExtra(
                    TransactionBundle.TRANSACTION_TYPE, Transaction.RETRIEVE_TRANSACTION);
                mContext.startService(intent);
              }
            });
        break;
    }

    // Hide the indicators.
    mLockedIndicator.setVisibility(View.GONE);
    mDeliveredIndicator.setVisibility(View.GONE);
    mDetailsIndicator.setVisibility(View.GONE);
    updateAvatarView(mMessageItem.mAddress, false);
  }