public MessageListItem(Context context) {
    super(context);
    mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();

    if (sDefaultContactImage == null) {
      sDefaultContactImage = context.getResources().getDrawable(R.drawable.ic_contact_picture);
    }
  }
  public MessageListItem(Context context, AttributeSet attrs) {
    super(context, attrs);

    int color = mContext.getResources().getColor(R.color.timestamp_color);
    mColorSpan = new ForegroundColorSpan(color);
    mDefaultCountryIso = MmsApp.getApplication().getCurrentCountryIso();

    if (sDefaultContactImage == null) {
      sDefaultContactImage = context.getResources().getDrawable(R.drawable.ic_contact_picture);
    }
  }
  @Override
  protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    mScreen = getPreferenceManager().createPreferenceScreen(this);
    setPreferenceScreen(mScreen);

    mDefaultTelephonyManager = MmsApp.getApplication().getTelephonyManager();
    mTelephonyManagers = new ArrayList<TelephonyManager>(2);
    mTelephonies = new ArrayList<ITelephony>(2);

    int phoneCount = mDefaultTelephonyManager.getPhoneCount();
    for (int i = 0; i < phoneCount; ++i) {
      TelephonyManager tm = MmsApp.getApplication().getTelephonyManager(i);
      mTelephonyManagers.add(tm);
      if (tm.hasIccCard() && tm.getSimState() == TelephonyManager.SIM_STATE_READY) {
        ITelephony telephony =
            ITelephony.Stub.asInterface(
                ServiceManager.getService(
                    PhoneFactory.getServiceName(Context.TELEPHONY_SERVICE, i)));
        mTelephonies.add(telephony);
      } else {
        mTelephonies.add(null); // just act as a place holder in the list
      }
    }

    Intent intent = getIntent();
    mMode = intent.getIntExtra(Mode.KEY, Mode.NIL);
    switch (mMode) {
      case Mode.MANAGE_MSG:
        handleManageSimMsg();
        break;
      case Mode.SMSC:
        handleSMSC();
        break;
      default:
        finish();
    }
  }
  @Override
  public void onReceive(Context context, Intent intent) {
    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
      Log.v(TAG, "Intent received: " + intent);
    }

    String action = intent.getAction();
    if (action.equals(Mms.Intents.CONTENT_CHANGED_ACTION)) {
      Uri changed = (Uri) intent.getParcelableExtra(Mms.Intents.DELETED_CONTENTS);
      MmsApp.getApplication().getPduLoaderManager().removePdu(changed);
    } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
      if (mConnMgr == null) {
        mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
      }
      NetworkInfo mmsNetworkInfo = mConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS);
      boolean available = mmsNetworkInfo.isAvailable();
      boolean isConnected = mmsNetworkInfo.isConnected();

      if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
        Log.v(TAG, "TYPE_MOBILE_MMS available = " + available + ", isConnected = " + isConnected);
      }

      // Wake up transact service when MMS data is available and isn't connected.
      if (available && !isConnected) {
        wakeUpService(context);
      }
    } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
      // We should check whether there are unread incoming
      // messages in the Inbox and then update the notification icon.
      // Called on the UI thread so don't block.
      MessagingNotification.nonBlockingUpdateNewMessageIndicator(
          context, MessagingNotification.THREAD_NONE, false);

      // Scan and send pending Mms once after boot completed since
      // ACTION_ANY_DATA_CONNECTION_STATE_CHANGED wasn't registered in a whole life cycle
      wakeUpService(context);
    }
  }
 public static String getLocalNumber() {
   if (null == sLocalNumber) {
     sLocalNumber = MmsApp.getApplication().getTelephonyManager().getLine1Number();
   }
   return sLocalNumber;
 }
  public void run() {
    Xlog.d(MmsApp.TXN_TAG, "NotificationTransaction: run()");
    DownloadManager downloadManager = DownloadManager.getInstance();
    // boolean autoDownload = downloadManager.isAuto();
    // boolean dataSuspended = (MmsApp.getApplication().getTelephonyManager().getDataState() ==
    //        TelephonyManager.DATA_SUSPENDED);
    boolean autoDownload = false;
    boolean dataSuspended = false;
    // add for gemini
    if (FeatureOption.MTK_GEMINI_SUPPORT) {
      autoDownload = downloadManager.isAuto(mSimId);
      int datastate =
          MmsApp.getApplication()
              .getTelephonyManager()
              .getDataStateGemini(SIMInfo.getSlotById(mContext, mSimId));
      dataSuspended =
          (datastate == TelephonyManager.DATA_SUSPENDED
              || datastate == TelephonyManager.DATA_DISCONNECTED);
    } else {
      autoDownload = downloadManager.isAuto();
      dataSuspended =
          (MmsApp.getApplication().getTelephonyManager().getDataState()
              == TelephonyManager.DATA_SUSPENDED);
    }

    try {
      if (LOCAL_LOGV) {
        Log.v(TAG, "Notification transaction launched: " + this);
      }

      // By default, we set status to STATUS_DEFERRED because we
      // should response MMSC with STATUS_DEFERRED when we cannot
      // download a MM immediately.
      int status = STATUS_DEFERRED;

      // Check expiry state
      Date CurrentDate = new Date(System.currentTimeMillis());
      Date ExpiryDate = new Date(mNotificationInd.getExpiry() * 1000);
      Xlog.d(
          MmsApp.TXN_TAG,
          "expiry time="
              + ExpiryDate.toLocaleString()
              + "\t current="
              + CurrentDate.toLocaleString());

      // MTK_OP01_PROTECT_START
      /*
      String optr = SystemProperties.get("ro.operator.optr");
      if (optr.equals("OP01")) {
          // Check Message size
          int msgSize = 0;
          Cursor cursor = SqliteWrapper.query(mContext, mContext.getContentResolver(),
                           mUri, new String[] {Mms.MESSAGE_SIZE}, null, null, null);
          if (cursor != null && cursor.getCount() == 1 && cursor.moveToFirst()) {
              try{
                  msgSize = cursor.getInt(0);
                  Xlog.v(MmsApp.TXN_TAG, "msg Size = " + msgSize);
              }finally{
                  cursor.close();
              }
          }

          String netWorkType = null;
          int slotId = -1;
          if (FeatureOption.MTK_GEMINI_SUPPORT) {
              // convert sim id to slot id
              slotId = SIMInfo.getSlotById(mContext, mSimId);
              netWorkType = SystemProperties.get(slotId == 0 ?
                      TelephonyProperties.PROPERTY_CS_NETWORK_TYPE : TelephonyProperties.PROPERTY_CS_NETWORK_TYPE_2);
          } else {
              netWorkType = SystemProperties.get(TelephonyProperties.PROPERTY_CS_NETWORK_TYPE);
          }

          boolean bTDNetwork = Integer.parseInt(netWorkType) > 2 ? true : false;
          if ((!bTDNetwork && MmsConfig.getReceiveMmsLimitFor2G() < msgSize/1024)
                  || (bTDNetwork && MmsConfig.getReceiveMmsLimitForTD() < msgSize/1024)) {
              Xlog.v(MmsApp.TXN_TAG, "Message size exceed limitation, rejected.");

              status = STATUS_REJECTED;
              sendNotifyRespInd(status);
              return;
          }
      }
      */
      // MTK_OP01_PROTECT_END
      // Don't try to download when data is suspended, as it will fail, so defer download
      if (!autoDownload || dataSuspended) {
        Xlog.d(
            MmsApp.TXN_TAG,
            "Not autoDownload! autoDonwload=" + autoDownload + ", dataSuspended=" + dataSuspended);
        if (FeatureOption.MTK_GEMINI_SUPPORT) {
          downloadManager.markState(mUri, DownloadManager.STATE_UNSTARTED, mSimId);
        } else {
          downloadManager.markState(mUri, DownloadManager.STATE_UNSTARTED);
        }
        sendNotifyRespInd(status);
        return;
      }

      if (FeatureOption.MTK_GEMINI_SUPPORT) {
        downloadManager.markState(mUri, DownloadManager.STATE_DOWNLOADING, mSimId);
      } else {
        downloadManager.markState(mUri, DownloadManager.STATE_DOWNLOADING);
      }

      if (LOCAL_LOGV) {
        Log.v(TAG, "Content-Location: " + mContentLocation);
      }

      byte[] retrieveConfData = null;
      // We should catch exceptions here to response MMSC
      // with STATUS_DEFERRED.
      try {
        Xlog.d(MmsApp.TXN_TAG, "NotificationTransaction: before getpdu");
        retrieveConfData = getPdu(mContentLocation);
        Xlog.d(MmsApp.TXN_TAG, "NotificationTransaction: after getpdu");
      } catch (IOException e) {
        mTransactionState.setState(FAILED);
      }

      if (retrieveConfData != null) {
        GenericPdu pdu = new PduParser(retrieveConfData).parse();
        if ((pdu == null) || (pdu.getMessageType() != MESSAGE_TYPE_RETRIEVE_CONF)) {
          Log.e(TAG, "Invalid M-RETRIEVE.CONF PDU.");
          mTransactionState.setState(FAILED);
          status = STATUS_UNRECOGNIZED;
        } else {
          // Save the received PDU (must be a M-RETRIEVE.CONF).
          PduPersister p = PduPersister.getPduPersister(mContext);
          Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
          Xlog.d(MmsApp.TXN_TAG, "PDU Saved, Uri=" + uri + "\nDelete Notify Ind, Uri=" + mUri);
          // add for gemini
          if (FeatureOption.MTK_GEMINI_SUPPORT) {
            ContentResolver cr = mContext.getContentResolver();
            ContentValues values = new ContentValues(1);
            values.put(Mms.SIM_ID, mSimId);
            SqliteWrapper.update(mContext, cr, uri, values, null, null);
          }

          // set message size
          int messageSize = retrieveConfData.length;
          ContentValues sizeValue = new ContentValues();
          sizeValue.put(Mms.MESSAGE_SIZE, messageSize);
          SqliteWrapper.update(mContext, mContext.getContentResolver(), uri, sizeValue, null, null);

          // We have successfully downloaded the new MM. Delete the
          // M-NotifyResp.ind from Inbox.
          String notifId = mUri.getLastPathSegment();
          String msgId = uri.getLastPathSegment();
          if (!notifId.equals(msgId)) {
            SqliteWrapper.delete(mContext, mContext.getContentResolver(), mUri, null, null);
          }
          // Notify observers with newly received MM.
          mUri = uri;
          status = STATUS_RETRIEVED;
        }
      } else {
        Xlog.e(MmsApp.TXN_TAG, "retrieveConfData is null");
        mTransactionState.setState(FAILED);
        status = STATUS_UNRECOGNIZED;
      }

      // Check the status and update the result state of this Transaction.
      switch (status) {
        case STATUS_RETRIEVED:
          mTransactionState.setState(SUCCESS);
          break;
        case STATUS_DEFERRED:
          // STATUS_DEFERRED, may be a failed immediate retrieval.
          if (mTransactionState.getState() == INITIALIZED) {
            mTransactionState.setState(SUCCESS);
          }
          break;
      }
      // if the status is STATUS_UNRECOGNIZED, this happened when we don't get mms pdu from server,
      // this may be a server problem or network problem.
      // our policy is will retry later, so we must response a deferred status not this one.
      // otherwise the server may delete this mms, and when we retry it, it's another mms created by
      // server to
      // inform us that the old mms is not exist yet.
      if (status == STATUS_UNRECOGNIZED) {
        status = STATUS_DEFERRED;
      }
      sendNotifyRespInd(status);

      // Make sure this thread isn't over the limits in message count.
      Recycler.getMmsRecycler().deleteOldMessagesInSameThreadAsMessage(mContext, mUri);
    } catch (Throwable t) {
      Log.e(TAG, Log.getStackTraceString(t));
      if (null != mUri) {
        Recycler.getMmsRecycler().deleteOldMessagesInSameThreadAsMessage(mContext, mUri);
      }
    } finally {
      mTransactionState.setContentUri(mUri);
      if (!autoDownload /*|| dataSuspended*/ /*comment this case for 81452*/) {
        // Always mark the transaction successful for deferred
        // download since any error here doesn't make sense.
        mTransactionState.setState(SUCCESS);
      }
      if (mTransactionState.getState() != SUCCESS) {
        mTransactionState.setState(FAILED);
        Xlog.w(MmsApp.TXN_TAG, "NotificationTransaction failed.");
      }
      notifyObservers();
    }
  }
  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);
  }