/**
   * This method is used if this is a "replace short message" SMS. We find any existing message that
   * matches the incoming message's originating address and protocol identifier. If there is one, we
   * replace its fields with those of the new message. Otherwise, we store the new message as usual.
   *
   * <p>See TS 23.040 9.2.3.9.
   */
  private Uri replaceMessage(Context context, SmsMessage[] msgs, int error) {
    SmsMessage sms = msgs[0];
    ContentValues values = extractContentValues(sms);
    values.put(Sms.ERROR_CODE, error);
    int pduCount = msgs.length;

    if (pduCount == 1) {
      // There is only one part, so grab the body directly.
      values.put(Inbox.BODY, replaceFormFeeds(sms.getDisplayMessageBody()));
    } else {
      // Build up the body from the parts.
      StringBuilder body = new StringBuilder();
      for (int i = 0; i < pduCount; i++) {
        sms = msgs[i];
        if (sms.mWrappedSmsMessage != null) {
          body.append(sms.getDisplayMessageBody());
        }
      }
      values.put(Inbox.BODY, replaceFormFeeds(body.toString()));
    }

    ContentResolver resolver = context.getContentResolver();
    String originatingAddress = sms.getOriginatingAddress();
    int protocolIdentifier = sms.getProtocolIdentifier();
    String selection = Sms.ADDRESS + " = ? AND " + Sms.PROTOCOL + " = ?";
    String[] selectionArgs =
        new String[] {originatingAddress, Integer.toString(protocolIdentifier)};

    Cursor cursor =
        SqliteWrapper.query(
            context,
            resolver,
            Inbox.CONTENT_URI,
            REPLACE_PROJECTION,
            selection,
            selectionArgs,
            null);

    if (cursor != null) {
      try {
        if (cursor.moveToFirst()) {
          long messageId = cursor.getLong(REPLACE_COLUMN_ID);
          Uri messageUri = ContentUris.withAppendedId(Sms.CONTENT_URI, messageId);

          SqliteWrapper.update(context, resolver, messageUri, values, null, null);
          return messageUri;
        }
      } finally {
        cursor.close();
      }
    }
    return storeMessage(context, msgs, error);
  }
  /// M:Code analyze 011,add for setting the mms being downloading when shutdown to unrecognized
  /// after boot complete again,have to manual download @{
  public static void setNotificationIndUnstarted(final Context context) {
    MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted");
    Cursor cursor =
        SqliteWrapper.query(
            context,
            context.getContentResolver(),
            Mms.CONTENT_URI,
            new String[] {Mms._ID, Mms.STATUS},
            Mms.MESSAGE_TYPE + "=" + PduHeaders.MESSAGE_TYPE_NOTIFICATION_IND,
            null,
            null);
    if (cursor != null) {
      try {
        int count = cursor.getCount();
        MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted: Message Size=" + count);

        if (count == 0) {
          return;
        }

        ContentValues values = null;
        int id = 0;
        int status = 0;
        while (cursor.moveToNext()) {
          id = cursor.getInt(0);
          status = cursor.getInt(1);
          MmsLog.d(
              MmsApp.TXN_TAG, "setNotificationIndUnstarted: MsgId=" + id + "; status=" + status);

          if (DownloadManager.STATE_DOWNLOADING == (status & ~DownloadManager.DEFERRED_MASK)) {
            values = new ContentValues(1);
            values.put(Mms.STATUS, PduHeaders.STATUS_UNRECOGNIZED);
            SqliteWrapper.update(
                context,
                context.getContentResolver(),
                Mms.CONTENT_URI,
                values,
                Mms._ID + "=" + id,
                null);
          }
        }
      } catch (SQLiteDiskIOException e) {
        // Ignore
        MmsLog.e(
            MmsApp.TXN_TAG, "SQLiteDiskIOException caught while set notification ind unstart", e);
      } finally {
        cursor.close();
      }
    } else {
      MmsLog.d(MmsApp.TXN_TAG, "setNotificationIndUnstarted: no pending messages.");
    }
  }
  /// M:Code analyze 009,add for setting the pending mms failed,mainly using after boot complete @{
  public static void setPendingMmsFailed(final Context context) {
    MmsLog.d(MmsApp.TXN_TAG, "setPendingMmsFailed");
    Cursor cursor =
        PduPersister.getPduPersister(context)
            .getPendingMessages(Long.MAX_VALUE /*System.currentTimeMillis()*/);
    if (cursor != null) {
      try {
        int count = cursor.getCount();
        MmsLog.d(MmsApp.TXN_TAG, "setPendingMmsFailed: Pending Message Size=" + count);

        if (count == 0) {
          return;
        }
        DefaultRetryScheme scheme = new DefaultRetryScheme(context, 100);
        ContentValues values = null;
        int columnIndex = 0;
        int columnType = 0;
        int id = 0;
        int type = 0;
        while (cursor.moveToNext()) {
          columnIndex = cursor.getColumnIndexOrThrow(PendingMessages._ID);
          id = cursor.getInt(columnIndex);

          columnType = cursor.getColumnIndexOrThrow(PendingMessages.MSG_TYPE);
          type = cursor.getInt(columnType);

          MmsLog.d(MmsApp.TXN_TAG, "setPendingMmsFailed: type=" + type + "; MsgId=" + id);

          if (type == PduHeaders.MESSAGE_TYPE_SEND_REQ) {
            values = new ContentValues(2);
            values.put(PendingMessages.ERROR_TYPE, MmsSms.ERR_TYPE_GENERIC_PERMANENT);
            values.put(PendingMessages.RETRY_INDEX, scheme.getRetryLimit());
            SqliteWrapper.update(
                context,
                context.getContentResolver(),
                PendingMessages.CONTENT_URI,
                values,
                PendingMessages._ID + "=" + id,
                null);
          }
        }
      } catch (SQLiteDiskIOException e) {
        // Ignore
        MmsLog.e(
            MmsApp.TXN_TAG, "SQLiteDiskIOException caught while set pending message failed", e);
      } finally {
        cursor.close();
      }
    } else {
      MmsLog.d(MmsApp.TXN_TAG, "setPendingMmsFailed: no pending MMS.");
    }
  }
  public static void setPendingSmsFailed(final Context context) {
    Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed");
    Cursor cursor =
        SqliteWrapper.query(
            context,
            context.getContentResolver(),
            Sms.CONTENT_URI,
            new String[] {Sms._ID},
            Sms.TYPE
                + "="
                + Sms.MESSAGE_TYPE_OUTBOX
                + " OR "
                + Sms.TYPE
                + "="
                + Sms.MESSAGE_TYPE_QUEUED,
            null,
            null);
    if (cursor != null) {
      try {
        int count = cursor.getCount();
        Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: Message Size=" + count);

        if (count == 0) {
          return;
        }

        ContentValues values = null;
        int id = 0;
        while (cursor.moveToNext()) {
          id = cursor.getInt(0);
          Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: MsgId=" + id);
          values = new ContentValues(1);
          values.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED);
          SqliteWrapper.update(
              context,
              context.getContentResolver(),
              Sms.CONTENT_URI,
              values,
              Sms._ID + "=" + id,
              null);
        }
      } catch (SQLiteDiskIOException e) {
        Xlog.e(MmsApp.TXN_TAG, "SQLiteDiskIOException caught while set sms failed", e);
      } finally {
        cursor.close();
      }
    } else {
      Xlog.d(MmsApp.TXN_TAG, "setPendingSmsFailed: no pending messages.");
    }
  }
  /**
   * Move all messages that are in the outbox to the queued state
   *
   * @return The number of messages that were actually moved
   */
  private int moveOutboxMessagesToQueuedBox() {
    ContentValues values = new ContentValues(1);

    values.put(Sms.TYPE, Sms.MESSAGE_TYPE_QUEUED);

    int messageCount =
        SqliteWrapper.update(
            getApplicationContext(),
            getContentResolver(),
            Outbox.CONTENT_URI,
            values,
            "type = " + Sms.MESSAGE_TYPE_OUTBOX,
            null);
    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
      Log.v(TAG, "moveOutboxMessagesToQueuedBox messageCount: " + messageCount);
    }
    return messageCount;
  }
  /**
   * Move all messages that are in the outbox to the failed state and set them to unread.
   *
   * @return The number of messages that were actually moved
   */
  private int moveOutboxMessagesToFailedBox() {
    ContentValues values = new ContentValues(3);

    values.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED);
    values.put(Sms.ERROR_CODE, SmsManager.RESULT_ERROR_GENERIC_FAILURE);
    values.put(Sms.READ, Integer.valueOf(0));

    int messageCount =
        SqliteWrapper.update(
            getApplicationContext(),
            getContentResolver(),
            Outbox.CONTENT_URI,
            values,
            "type = " + Sms.MESSAGE_TYPE_OUTBOX,
            null);
    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
      Log.v(TAG, "moveOutboxMessagesToFailedBox messageCount: " + messageCount);
    }
    return messageCount;
  }
Example #7
0
  private void writeInboxMessage(long subId, byte[] pushData) {
    final GenericPdu pdu = new PduParser(pushData).parse();
    if (pdu == null) {
      Rlog.e(TAG, "Invalid PUSH PDU");
    }
    final PduPersister persister = PduPersister.getPduPersister(mContext);
    final int type = pdu.getMessageType();
    try {
      switch (type) {
        case MESSAGE_TYPE_DELIVERY_IND:
        case MESSAGE_TYPE_READ_ORIG_IND:
          {
            final long threadId = getDeliveryOrReadReportThreadId(mContext, pdu);
            if (threadId == -1) {
              // The associated SendReq isn't found, therefore skip
              // processing this PDU.
              Rlog.e(TAG, "Failed to find delivery or read report's thread id");
              break;
            }
            final Uri uri =
                persister.persist(
                    pdu,
                    Telephony.Mms.Inbox.CONTENT_URI,
                    true /*createThreadId*/,
                    true /*groupMmsEnabled*/,
                    null /*preOpenedFiles*/);
            if (uri == null) {
              Rlog.e(TAG, "Failed to persist delivery or read report");
              break;
            }
            // Update thread ID for ReadOrigInd & DeliveryInd.
            final ContentValues values = new ContentValues(1);
            values.put(Telephony.Mms.THREAD_ID, threadId);
            if (SqliteWrapper.update(
                    mContext,
                    mContext.getContentResolver(),
                    uri,
                    values,
                    null /*where*/,
                    null /*selectionArgs*/)
                != 1) {
              Rlog.e(TAG, "Failed to update delivery or read report thread id");
            }
            break;
          }
        case MESSAGE_TYPE_NOTIFICATION_IND:
          {
            final NotificationInd nInd = (NotificationInd) pdu;

            Bundle configs = SmsManager.getSmsManagerForSubscriber(subId).getCarrierConfigValues();
            if (configs != null
                && configs.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID, false)) {
              final byte[] contentLocation = nInd.getContentLocation();
              if ('=' == contentLocation[contentLocation.length - 1]) {
                byte[] transactionId = nInd.getTransactionId();
                byte[] contentLocationWithId =
                    new byte[contentLocation.length + transactionId.length];
                System.arraycopy(
                    contentLocation, 0, contentLocationWithId, 0, contentLocation.length);
                System.arraycopy(
                    transactionId,
                    0,
                    contentLocationWithId,
                    contentLocation.length,
                    transactionId.length);
                nInd.setContentLocation(contentLocationWithId);
              }
            }
            if (!isDuplicateNotification(mContext, nInd)) {
              final Uri uri =
                  persister.persist(
                      pdu,
                      Telephony.Mms.Inbox.CONTENT_URI,
                      true /*createThreadId*/,
                      true /*groupMmsEnabled*/,
                      null /*preOpenedFiles*/);
              if (uri == null) {
                Rlog.e(TAG, "Failed to save MMS WAP push notification ind");
              }
            } else {
              Rlog.d(
                  TAG,
                  "Skip storing duplicate MMS WAP push notification ind: "
                      + new String(nInd.getContentLocation()));
            }
            break;
          }
        default:
          Log.e(TAG, "Received unrecognized WAP Push PDU.");
      }
    } catch (MmsException e) {
      Log.e(TAG, "Failed to save MMS WAP push data: type=" + type, e);
    } catch (RuntimeException e) {
      Log.e(TAG, "Unexpected RuntimeException in persisting MMS WAP push data", e);
    }
  }
  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();
    }
  }
    @Override
    protected Void doInBackground(Intent... intents) {
      Intent intent = intents[0];
      Xlog.d(
          MmsApp.TXN_TAG,
          "do In Background, slotId=" + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0));
      // Get raw PDU push-data from the message and parse it
      byte[] pushData = intent.getByteArrayExtra("data");
      PduParser parser = new PduParser(pushData);
      GenericPdu pdu = parser.parse();

      if (null == pdu) {
        Log.e(TAG, "Invalid PUSH data");
        return null;
      }

      PduPersister p = PduPersister.getPduPersister(mContext);
      ContentResolver cr = mContext.getContentResolver();
      int type = pdu.getMessageType();
      long threadId = -1;

      try {
        switch (type) {
          case MESSAGE_TYPE_DELIVERY_IND:
            Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_DELIVERY_IND");
          case MESSAGE_TYPE_READ_ORIG_IND:
            {
              if (type == MESSAGE_TYPE_READ_ORIG_IND) {
                Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_READ_ORIG_IND");
              }
              threadId = findThreadId(mContext, pdu, type);
              if (threadId == -1) {
                // The associated SendReq isn't found, therefore skip
                // processing this PDU.
                break;
              }

              Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
              // Update thread ID for ReadOrigInd & DeliveryInd.
              ContentValues values = new ContentValues(1);
              values.put(Mms.THREAD_ID, threadId);
              SqliteWrapper.update(mContext, cr, uri, values, null, null);
              break;
            }
          case MESSAGE_TYPE_NOTIFICATION_IND:
            {
              Xlog.d(MmsApp.TXN_TAG, "type=MESSAGE_TYPE_NOTIFICATION_IND");
              NotificationInd nInd = (NotificationInd) pdu;

              if (MmsConfig.getTransIdEnabled()) {
                byte[] contentLocation = nInd.getContentLocation();
                if ('=' == contentLocation[contentLocation.length - 1]) {
                  byte[] transactionId = nInd.getTransactionId();
                  byte[] contentLocationWithId =
                      new byte[contentLocation.length + transactionId.length];
                  System.arraycopy(
                      contentLocation, 0, contentLocationWithId, 0, contentLocation.length);
                  System.arraycopy(
                      transactionId,
                      0,
                      contentLocationWithId,
                      contentLocation.length,
                      transactionId.length);
                  nInd.setContentLocation(contentLocationWithId);
                }
              }

              if (!isDuplicateNotification(mContext, nInd)) {
                Uri uri = p.persist(pdu, Inbox.CONTENT_URI);
                // add for gemini
                if (FeatureOption.MTK_GEMINI_SUPPORT) {
                  // update pdu
                  ContentValues values = new ContentValues(2);
                  SIMInfo si =
                      SIMInfo.getSIMInfoBySlot(
                          mContext, intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1));
                  if (null == si) {
                    Xlog.e(
                        MmsApp.TXN_TAG,
                        "PushReceiver:SIMInfo is null for slot "
                            + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1));
                    break;
                  }
                  values.put(Mms.SIM_ID, si.mSimId);
                  values.put(WapPush.SERVICE_ADDR, intent.getStringExtra(WapPush.SERVICE_ADDR));
                  SqliteWrapper.update(mContext, cr, uri, values, null, null);
                  Xlog.d(
                      MmsApp.TXN_TAG,
                      "save notification slotId="
                          + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0)
                          + "\tsimId="
                          + si.mSimId
                          + "\tsc="
                          + intent.getStringExtra(WapPush.SERVICE_ADDR)
                          + "\taddr="
                          + intent.getStringExtra(WapPush.ADDR));

                  // update pending messages
                  long msgId = 0;
                  Cursor cursor =
                      SqliteWrapper.query(
                          mContext,
                          mContext.getContentResolver(),
                          uri,
                          new String[] {Mms._ID},
                          null,
                          null,
                          null);
                  if (cursor != null && cursor.getCount() == 1 && cursor.moveToFirst()) {
                    try {
                      msgId = cursor.getLong(0);
                      Xlog.d(MmsApp.TXN_TAG, "msg id = " + msgId);
                    } finally {
                      cursor.close();
                    }
                  }

                  Uri.Builder uriBuilder = PendingMessages.CONTENT_URI.buildUpon();
                  uriBuilder.appendQueryParameter("protocol", "mms");
                  uriBuilder.appendQueryParameter("message", String.valueOf(msgId));
                  Cursor pendingCs =
                      SqliteWrapper.query(
                          mContext,
                          mContext.getContentResolver(),
                          uriBuilder.build(),
                          null,
                          null,
                          null,
                          null);
                  if (pendingCs != null) {
                    try {
                      if ((pendingCs.getCount() == 1) && pendingCs.moveToFirst()) {
                        ContentValues valuesforPending = new ContentValues();
                        valuesforPending.put(PendingMessages.SIM_ID, si.mSimId);
                        int columnIndex = pendingCs.getColumnIndexOrThrow(PendingMessages._ID);
                        long id = pendingCs.getLong(columnIndex);
                        SqliteWrapper.update(
                            mContext,
                            mContext.getContentResolver(),
                            PendingMessages.CONTENT_URI,
                            valuesforPending,
                            PendingMessages._ID + "=" + id,
                            null);
                      } else {
                        Xlog.w(
                            MmsApp.TXN_TAG,
                            "can not find message to set pending sim id, msgId=" + msgId);
                      }
                    } finally {
                      pendingCs.close();
                    }
                  }
                } else {
                  ContentValues value = new ContentValues(1);
                  value.put(WapPush.SERVICE_ADDR, intent.getStringExtra(WapPush.SERVICE_ADDR));
                  SqliteWrapper.update(mContext, cr, uri, value, null, null);
                  Xlog.d(
                      MmsApp.TXN_TAG,
                      "save notification,"
                          + "\tsc="
                          + intent.getStringExtra(WapPush.SERVICE_ADDR)
                          + "\taddr="
                          + intent.getStringExtra(WapPush.ADDR));
                }

                // Start service to finish the notification transaction.
                Intent svc = new Intent(mContext, TransactionService.class);
                svc.putExtra(TransactionBundle.URI, uri.toString());
                svc.putExtra(
                    TransactionBundle.TRANSACTION_TYPE, Transaction.NOTIFICATION_TRANSACTION);
                if (FeatureOption.MTK_GEMINI_SUPPORT) {
                  SIMInfo si =
                      SIMInfo.getSIMInfoBySlot(
                          mContext, intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1));
                  if (null == si) {
                    Xlog.e(
                        MmsApp.TXN_TAG,
                        "PushReceiver: SIMInfo is null for slot "
                            + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1));
                    break;
                  }
                  int simId = (int) si.mSimId;
                  svc.putExtra(Phone.GEMINI_SIM_ID_KEY, simId);
                  // svc.putExtra(Phone.GEMINI_SIM_ID_KEY,
                  // intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, 0));
                }
                mContext.startService(svc);
              } else if (LOCAL_LOGV) {
                Log.v(
                    TAG,
                    "Skip downloading duplicate message: " + new String(nInd.getContentLocation()));
              }
              break;
            }
          default:
            Log.e(TAG, "Received unrecognized PDU.");
        }
      } catch (MmsException e) {
        Log.e(TAG, "Failed to save the data from PUSH: type=" + type, e);
      } catch (RuntimeException e) {
        Log.e(TAG, "Unexpected RuntimeException.", e);
      } finally {
        raisePriority(mContext, false);
        Xlog.d(MmsApp.TXN_TAG, "Normal priority");
      }

      if (LOCAL_LOGV) {
        Log.v(TAG, "PUSH Intent processed.");
      }

      return null;
    }