private void handleSmsReceived(Intent intent, int error) {
    SmsMessage[] msgs = Intents.getMessagesFromIntent(intent);
    String format = intent.getStringExtra("format");
    Uri messageUri = insertMessage(this, msgs, error, format);

    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
      SmsMessage sms = msgs[0];
      Log.v(
          TAG,
          "handleSmsReceived"
              + (sms.isReplace() ? "(replace)" : "")
              + " messageUri: "
              + messageUri
              + ", address: "
              + sms.getOriginatingAddress()
              + ", body: "
              + sms.getMessageBody());
    }

    if (messageUri != null) {
      long threadId = MessagingNotification.getSmsThreadId(this, messageUri);
      // Called off of the UI thread so ok to block.
      Log.d(TAG, "handleSmsReceived messageUri: " + messageUri + " threadId: " + threadId);
      MessagingNotification.blockingUpdateNewMessageIndicator(this, threadId, false);
    }
  }
  private void handleBootCompleted() {
    // Some messages may get stuck in the outbox. At this point, they're probably irrelevant
    // to the user, so mark them as failed and notify the user, who can then decide whether to
    // resend them manually.
    int numMoved = moveOutboxMessagesToFailedBox();
    if (numMoved > 0) {
      MessagingNotification.notifySendFailed(getApplicationContext(), true);
    }

    // Send any queued messages that were waiting from before the reboot.
    sendFirstQueuedMessage();

    // Called off of the UI thread so ok to block.
    MessagingNotification.blockingUpdateNewMessageIndicator(
        this, MessagingNotification.THREAD_ALL, false);
  }
 private void messageFailedToSend(Uri uri, int error) {
   if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE) || LogTag.DEBUG_SEND) {
     Log.v(TAG, "messageFailedToSend msg failed uri: " + uri + " error: " + error);
   }
   Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_FAILED, error);
   MessagingNotification.notifySendFailed(getApplicationContext(), true);
 }
  @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);
    }
  }
  @Override
  public void onReceive(Context context, Intent intent) {
    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
      Log.v(TAG, "Intent received: " + intent);
    }
    Xlog.d(MmsApp.LOG_TAG, "onReceive(): intent=" + intent.toString());
    String action = intent.getAction();
    if (action.equals(Mms.Intents.CONTENT_CHANGED_ACTION)) {
      final Intent mIntent = intent;
      new Thread(
              new Runnable() {
                @Override
                public void run() {
                  Uri changed = (Uri) mIntent.getParcelableExtra(Mms.Intents.DELETED_CONTENTS);
                  PduCache.getInstance().purge(changed);
                  Xlog.d(MmsApp.TXN_TAG, "Mms.Intents.CONTENT_CHANGED_ACTION: " + changed);
                }
              })
          .start();
    } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
      String state = intent.getStringExtra(Phone.STATE_KEY);

      if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
        Log.v(TAG, "ANY_DATA_STATE event received: " + state);
      }

      String apnType = intent.getStringExtra(Phone.DATA_APN_TYPE_KEY);

      // if (state.equals("CONNECTED")) {
      if (Phone.APN_TYPE_MMS.equals(apnType)) {
        Xlog.d(
            MmsApp.TXN_TAG,
            "TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED, type is mms.");
        // if the network is not available for mms, keep listening
        ConnectivityManager ConnMgr =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = ConnMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS);
        if (ni != null && !ni.isAvailable()) {
          Xlog.d(MmsApp.TXN_TAG, "network is not available for mms, keep listening.");
          return;
        }

        unRegisterForConnectionStateChanges(context);
        // add for gemini
        if (FeatureOption.MTK_GEMINI_SUPPORT == true) {
          // conver slot id to sim id
          SIMInfo si =
              SIMInfo.getSIMInfoBySlot(
                  context, intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, Phone.GEMINI_SIM_1));
          if (null == si) {
            Xlog.e(
                MmsApp.TXN_TAG,
                "System event receiver: SIMInfo is null for slot "
                    + intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY, -1));
            return;
          }
          int simId = (int) si.mSimId;
          wakeUpServiceGemini(
              context, simId /*intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY,Phone.GEMINI_SIM_1)*/);
        } else {
          wakeUpService(context);
        }
      }
    } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
      Xlog.d(MmsApp.TXN_TAG, "Intent.ACTION_BOOT_COMPLETED");
      final Context contxt = context;
      new Thread(
              new Runnable() {
                public void run() {
                  setPendingMmsFailed(contxt);
                  setPendingSmsFailed(contxt);
                  setNotificationIndUnstarted(contxt);
                }
              })
          .start();
      // 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, false, false);
    } else if (action.equals(Intent.SIM_SETTINGS_INFO_CHANGED)) {
      int simId = (int) intent.getLongExtra("simid", -1);
      MessageUtils.simInfoMap.remove(simId);
      MessageUtils.getSimInfo(context, simId);
    } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
      saveDraft = (OnShutDownListener) ComposeMessageActivity.getComposeContext();
      if (saveDraft != null) {
        saveDraft.onShutDown();
      }
    } else if (action.equals(Intent.ACTION_SMS_DEFAULT_SIM_CHANGED)) {
      Xlog.d(MmsApp.LOG_TAG, "SMS default SIM changed.");
      mSimInforChangedListener =
          (OnSimInforChangedListener) ComposeMessageActivity.getComposeContext();
      if (mSimInforChangedListener != null) {
        mSimInforChangedListener.OnSimInforChanged();
      }
      mSimInforChangedListener = (OnSimInforChangedListener) ConversationList.getContext();
      if (mSimInforChangedListener != null) {
        mSimInforChangedListener.OnSimInforChanged();
      }
    } else if (action.equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
      MmsConfig.setDeviceStorageFullStatus(true);
    } else if (action.equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
      MmsConfig.setDeviceStorageFullStatus(false);
      MessagingNotification.cancelNotification(
          context, SmsRejectedReceiver.SMS_REJECTED_NOTIFICATION_ID);
    }
  }
  @Override
  public void onReceive(Context context, Intent intent) {
    if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
      Log.v(TAG, "Intent received: " + intent);
    }
    /// M:
    MmsLog.d(MmsApp.LOG_TAG, "onReceive(): intent=" + intent.toString());
    String action = intent.getAction();
    if (action.equals(Mms.Intents.CONTENT_CHANGED_ACTION)) {
      /// M:Code analyze 003, put in a new thread @{
      final Intent mIntent = intent;
      new Thread(
              new Runnable() {
                @Override
                public void run() {
                  Uri changed = (Uri) mIntent.getParcelableExtra(Mms.Intents.DELETED_CONTENTS);
                  if (changed != null) {
                    MmsApp.getApplication().getPduLoaderManager().removePdu(changed);
                  }
                  MmsLog.d(MmsApp.TXN_TAG, "Mms.Intents.CONTENT_CHANGED_ACTION: " + changed);
                }
              })
          .start();
      /// @}
    } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) {
      String state = intent.getStringExtra(EncapsulatedPhone.STATE_KEY);

      if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
        Log.v(TAG, "ANY_DATA_STATE event received: " + state);
      }
      /// M:Code analyze 004, modify the logic,if data connection change,unRegister the listener of
      /// connection changed and wake up transaction service,and add gemini logic @{
      String apnType = intent.getStringExtra(EncapsulatedPhone.DATA_APN_TYPE_KEY);

      // if (state.equals("CONNECTED")) {
      if (EncapsulatedPhone.APN_TYPE_MMS.equals(apnType)) {
        MmsLog.d(
            MmsApp.TXN_TAG,
            "TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED, type is mms.");
        // if the network is not available for mms, keep listening
        ConnectivityManager connMgr =
            (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_MMS);
        if (ni != null && !ni.isAvailable()) {
          MmsLog.d(MmsApp.TXN_TAG, "network is not available for mms, keep listening.");
          return;
        }

        unRegisterForConnectionStateChanges(context);
        // add for gemini
        if (EncapsulatedFeatureOption.MTK_GEMINI_SUPPORT) {
          // conver slot id to sim id
          SIMInfo si =
              SIMInfo.getSIMInfoBySlot(
                  context,
                  intent.getIntExtra(
                      EncapsulatedPhone.GEMINI_SIM_ID_KEY, EncapsulatedPhone.GEMINI_SIM_1));
          if (null == si) {
            MmsLog.e(
                MmsApp.TXN_TAG,
                "System event receiver: SIMInfo is null for slot "
                    + intent.getIntExtra(EncapsulatedPhone.GEMINI_SIM_ID_KEY, -1));
            return;
          }
          int simId = (int) si.getSimId();
          wakeUpServiceGemini(
              context, simId /*intent.getIntExtra(Phone.GEMINI_SIM_ID_KEY,Phone.GEMINI_SIM_1)*/);
        } else {
          wakeUpService(context);
        }
      }
      /// @}
    } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
      /// M:Code analyze 005, mark pending msg failed after boot complete @{
      MmsLog.d(MmsApp.TXN_TAG, "Intent.ACTION_BOOT_COMPLETED");
      final Context contxt = context;
      new Thread(
              new Runnable() {
                public void run() {
                  IpMessageUtils.getIpMessagePlugin(contxt)
                      .getServiceManager(contxt.getApplicationContext())
                      .startIpService();
                  setPendingMmsFailed(contxt);
                  setNotificationIndUnstarted(contxt);
                }
              })
          .start();
      /// @}
      // 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);
      /// M: when power off,save the chat setting. {@
      SharedPreferences sp =
          PreferenceManager.getDefaultSharedPreferences(contxt.getApplicationContext());
      final long unSavedthreadId = sp.getLong(ChatPreferenceActivity.CHAT_THREAD_ID, -1l);
      Log.v(TAG, "unSaved chatThreadSetting: " + unSavedthreadId);
      if (unSavedthreadId > 0) {
        final boolean mNotificationEnable =
            sp.getBoolean(ChatPreferenceActivity.ENABLE_NOTIFICATION, false);
        final String mMute = sp.getString(ChatPreferenceActivity.CHAT_MUTE, "0");
        final String mRingtone =
            sp.getString(
                ChatPreferenceActivity.CHAT_RINGTONE, ChatPreferenceActivity.DEFAULT_RINGTONE);
        final boolean mVibrate = sp.getBoolean(ChatPreferenceActivity.CHAT_VIBRATE, false);
        final long mMuteStart = sp.getLong(ChatPreferenceActivity.CHAT_MUTE_START, 0);
        new Thread() {
          public void run() {
            SharedPreferences spChatThreadId =
                PreferenceManager.getDefaultSharedPreferences(contxt.getApplicationContext());
            Uri uri =
                ContentUris.withAppendedId(
                    Uri.parse(ChatPreferenceActivity.CHAT_SETTINGS_URI), unSavedthreadId);
            ContentValues values = new ContentValues();
            values.put(ThreadSettings.NOTIFICATION_ENABLE, mNotificationEnable ? 1 : 0);
            values.put(ThreadSettings.MUTE, Integer.parseInt(mMute));
            values.put(ThreadSettings.MUTE_START, mMuteStart);
            values.put(ThreadSettings.RINGTONE, mRingtone);
            values.put(ThreadSettings.VIBRATE, mVibrate ? 1 : 0);
            contxt.getContentResolver().update(uri, values, null, null);
            SharedPreferences.Editor editor = spChatThreadId.edit();
            editor.putLong(ChatPreferenceActivity.CHAT_THREAD_ID, -1l);
            editor.commit();
            if (MmsConfig.getFolderModeEnabled()) {
              MuteCache.setMuteCache(
                  unSavedthreadId, Long.parseLong(mMute), mMuteStart, mNotificationEnable);
            }
          }
        }.start();
      }
      /// M: @}
      /// M:Code analyze 006,add for listening sim setting info changed @{
    } else if (action.equals(EncapsulatedAction.SIM_SETTINGS_INFO_CHANGED)) {
      int simId = (int) intent.getLongExtra("simid", -1);
      MessageUtils.simInfoMap.remove(simId);
      MessageUtils.getSimInfo(context, simId);
      /// @}
      /// M:Code analyze 001,add for save draft mms when received event of shutdown @{
    } else if (action.equals(Intent.ACTION_SHUTDOWN)) {
      mSaveDraft = (OnShutDownListener) ComposeMessageActivity.getComposeContext();
      if (mSaveDraft != null) {
        mSaveDraft.onShutDown();
      }
      /// @}
      /// M:Code analyze 002,add for listening the changing of sim info @{
    } else if (action.equals(EncapsulatedAction.ACTION_SMS_DEFAULT_SIM_CHANGED)) {
      MmsLog.d(MmsApp.LOG_TAG, "SMS default SIM changed.");
      mSimInforChangedListener =
          (OnSimInforChangedListener) ComposeMessageActivity.getComposeContext();
      if (mSimInforChangedListener != null) {
        mSimInforChangedListener.onSimInforChanged();
      }
      mSimInforChangedListener = (OnSimInforChangedListener) ConversationList.getContext();
      if (mSimInforChangedListener != null) {
        mSimInforChangedListener.onSimInforChanged();
      }
      /// @}
      /// M:Code analyze 007,add for listening device storage full or not @{
    } else if (action.equals(Intent.ACTION_DEVICE_STORAGE_FULL)) {
      MmsConfig.setDeviceStorageFullStatus(true);
    } else if (action.equals(Intent.ACTION_DEVICE_STORAGE_NOT_FULL)) {
      MmsConfig.setDeviceStorageFullStatus(false);
      MessagingNotification.cancelNotification(
          context, SmsRejectedReceiver.SMS_REJECTED_NOTIFICATION_ID);
      /// @}
      /// M: new feature, add default quick_text @{
    } else if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
      if (MmsConfig.getInitQuickText()) {
        return;
      }
      final Context runContext = context;
      new Thread(
              new Runnable() {
                public void run() {
                  Cursor cursor =
                      runContext
                          .getContentResolver()
                          .query(
                              EncapsulatedTelephony.MmsSms.CONTENT_URI_QUICKTEXT,
                              null,
                              null,
                              null,
                              null);
                  // get delete and add ID in DB, id quick Text array
                  ArrayList<Integer> delAddID = new ArrayList<Integer>();
                  ArrayList<Integer> quickTextID = new ArrayList<Integer>();
                  if (cursor != null) {
                    try {
                      ArrayList<String> preQuickText = MmsConfig.getPreQuickText();
                      while (cursor.moveToNext()) {
                        int id = cursor.getInt(0);
                        String str = cursor.getString(1);
                        for (int i = 0; i < preQuickText.size(); i++) {
                          if (str.equals(preQuickText.get(i))) {
                            delAddID.add(new Integer(id));
                            quickTextID.add(new Integer(i));
                            break;
                          }
                        }
                      }
                    } finally {
                      cursor.close();
                    }
                  }
                  // delete old language default quick text
                  for (Integer i : delAddID) {
                    runContext
                        .getContentResolver()
                        .delete(
                            EncapsulatedTelephony.MmsSms.CONTENT_URI_QUICKTEXT,
                            _ID + "=" + i,
                            null);
                  }

                  // add new language default quick text
                  String[] default_quick_texts =
                      runContext.getResources().getStringArray(R.array.default_quick_texts);
                  for (int i = 0, j = 0; i < delAddID.size() && j < quickTextID.size(); i++, j++) {
                    ContentValues values = new ContentValues();
                    values.put(_ID, delAddID.get(i));
                    values.put("text", default_quick_texts[quickTextID.get(j)]);
                    runContext
                        .getContentResolver()
                        .insert(EncapsulatedTelephony.MmsSms.CONTENT_URI_QUICKTEXT, values);
                  }
                  MmsConfig.setPreQuickText(default_quick_texts);
                }
              })
          .start();
    }
    /// @}
  }
  private void handleSmsSent(Intent intent, int error) {
    Uri uri = intent.getData();
    mSending = false;
    boolean sendNextMsg = intent.getBooleanExtra(EXTRA_MESSAGE_SENT_SEND_NEXT, false);

    if (LogTag.DEBUG_SEND) {
      Log.v(
          TAG,
          "handleSmsSent uri: "
              + uri
              + " sendNextMsg: "
              + sendNextMsg
              + " mResultCode: "
              + mResultCode
              + " = "
              + translateResultCode(mResultCode)
              + " error: "
              + error);
    }

    if (mResultCode == Activity.RESULT_OK) {
      if (LogTag.DEBUG_SEND || Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
        Log.v(TAG, "handleSmsSent move message to sent folder uri: " + uri);
      }
      if (!Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_SENT, error)) {
        Log.e(TAG, "handleSmsSent: failed to move message " + uri + " to sent folder");
      }
      if (sendNextMsg) {
        sendFirstQueuedMessage();
      }

      // Update the notification for failed messages since they may be deleted.
      MessagingNotification.nonBlockingUpdateSendFailedNotification(this);
    } else if ((mResultCode == SmsManager.RESULT_ERROR_RADIO_OFF)
        || (mResultCode == SmsManager.RESULT_ERROR_NO_SERVICE)) {
      if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
        Log.v(TAG, "handleSmsSent: no service, queuing message w/ uri: " + uri);
      }
      // We got an error with no service or no radio. Register for state changes so
      // when the status of the connection/radio changes, we can try to send the
      // queued up messages.
      registerForServiceStateChanges();
      // We couldn't send the message, put in the queue to retry later.
      Sms.moveMessageToFolder(this, uri, Sms.MESSAGE_TYPE_QUEUED, error);
      mToastHandler.post(
          new Runnable() {
            public void run() {
              Toast.makeText(
                      SmsReceiverService.this,
                      getString(R.string.message_queued),
                      Toast.LENGTH_SHORT)
                  .show();
            }
          });
    } else if (mResultCode == SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE) {
      mToastHandler.post(
          new Runnable() {
            public void run() {
              Toast.makeText(
                      SmsReceiverService.this,
                      getString(R.string.fdn_check_failure),
                      Toast.LENGTH_SHORT)
                  .show();
            }
          });
    } else {
      messageFailedToSend(uri, error);
      if (sendNextMsg) {
        sendFirstQueuedMessage();
      }
    }
  }