private static AndroidHttpClient createHttpClient(Context context) {

    // Get Shared Preferences and User Defined User Agent for MMS
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    mUserAgent = prefs.getString(MessagingPreferenceActivity.USER_AGENT, MmsConfig.getUserAgent());
    if (mUserAgent == null || mUserAgent.equals("") || mUserAgent.equals("default")) {
      mUserAgent = MmsConfig.getUserAgent();
    } else if (mUserAgent.equals("custom")) {
      mUserAgent =
          prefs.getString(MessagingPreferenceActivity.USER_AGENT_CUSTOM, MmsConfig.getUserAgent());
    }

    AndroidHttpClient client = AndroidHttpClient.newInstance(mUserAgent);

    HttpParams params = client.getParams();
    HttpProtocolParams.setContentCharset(params, "UTF-8");

    // set the socket timeout
    int soTimeout = MmsConfig.getHttpSocketTimeout();

    if (Log.isLoggable(LogTag.TRANSACTION, Log.DEBUG)) {
      Log.d(
          TAG,
          "[HttpUtils] createHttpClient w/ socket timeout "
              + soTimeout
              + " ms, "
              + ", UA="
              + mUserAgent);
    }
    HttpConnectionParams.setSoTimeout(params, soTimeout);
    return client;
  }
  private void sendNotifyRespInd(int status) throws MmsException, IOException {
    // Create the M-NotifyResp.ind
    NotifyRespInd notifyRespInd =
        new NotifyRespInd(
            PduHeaders.CURRENT_MMS_VERSION, mNotificationInd.getTransactionId(), status);

    // Pack M-NotifyResp.ind and send it
    if (MmsConfig.getNotifyWapMMSC()) {
      sendPdu(new PduComposer(mContext, notifyRespInd).make(), mContentLocation);
    } else {
      sendPdu(new PduComposer(mContext, notifyRespInd).make());
    }
  }
  // An alias (or commonly called "nickname") is:
  // Nickname must begin with a letter.
  // Only letters a-z, numbers 0-9, or . are allowed in Nickname field.
  public static boolean isAlias(String string) {
    if (!MmsConfig.isAliasEnabled()) {
      return false;
    }

    int len = string == null ? 0 : string.length();

    if (len < MmsConfig.getAliasMinChars() || len > MmsConfig.getAliasMaxChars()) {
      return false;
    }

    if (!Character.isLetter(string.charAt(0))) { // Nickname begins with a letter
      return false;
    }
    for (int i = 1; i < len; i++) {
      char c = string.charAt(i);
      if (!(Character.isLetterOrDigit(c) || c == '.')) {
        return false;
      }
    }

    return true;
  }
  private void sendNotifyRespInd(int status) throws MmsException, IOException {
    // Create the M-NotifyResp.ind
    Xlog.v(MmsApp.TXN_TAG, "NotificationTransaction: sendNotifyRespInd()");
    NotifyRespInd notifyRespInd =
        new NotifyRespInd(
            PduHeaders.CURRENT_MMS_VERSION, mNotificationInd.getTransactionId(), status);

    // MTK_OP01_PROTECT_START
    String optr = SystemProperties.get("ro.operator.optr");
    if (optr.equals("OP01")) {
      // X-Mms-Report-Allowed Optional
      SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
      boolean reportAllowed = true;
      if (FeatureOption.MTK_GEMINI_SUPPORT) {
        reportAllowed =
            prefs.getBoolean(
                Integer.toString(mSimId)
                    + "_"
                    + MessagingPreferenceActivity.MMS_ENABLE_TO_SEND_DELIVERY_REPORT,
                true);
      } else {
        reportAllowed =
            prefs.getBoolean(MessagingPreferenceActivity.MMS_ENABLE_TO_SEND_DELIVERY_REPORT, true);
      }

      Xlog.d(MmsApp.TXN_TAG, "reportAllowed: " + reportAllowed);

      try {
        notifyRespInd.setReportAllowed(reportAllowed ? PduHeaders.VALUE_YES : PduHeaders.VALUE_NO);
      } catch (InvalidHeaderValueException ihve) {
        // do nothing here
        Xlog.e(MmsApp.TXN_TAG, "notifyRespInd.setReportAllowed Failed !!");
      }
    }
    // MTK_OP01_PROTECT_END

    // Pack M-NotifyResp.ind and send it
    if (MmsConfig.getNotifyWapMMSC()) {
      sendPdu(new PduComposer(mContext, notifyRespInd).make(), mContentLocation);
    } else {
      sendPdu(new PduComposer(mContext, notifyRespInd).make());
    }
  }
  @Override
  public boolean onPrepareOptionsMenu(Menu menu) {
    if (isFinishing()) {
      return false;
    }
    menu.clear();

    SlideModel slide = mSlideshowModel.get(mPosition);

    if (slide == null) {
      return false;
    }

    // Preview slideshow.
    menu.add(0, MENU_PREVIEW_SLIDESHOW, 0, R.string.preview_slideshow)
        .setIcon(com.android.internal.R.drawable.ic_menu_play_clip);

    // Text
    if (slide.hasText() && !TextUtils.isEmpty(slide.getText().getText())) {
      // "Change text" if text is set.
      menu.add(0, MENU_REMOVE_TEXT, 0, R.string.remove_text)
          .setIcon(R.drawable.ic_menu_remove_text);
    }

    // Picture
    if (slide.hasImage()) {
      menu.add(0, MENU_DEL_PICTURE, 0, R.string.remove_picture)
          .setIcon(R.drawable.ic_menu_remove_picture);
    } else if (!slide.hasVideo()) {
      menu.add(0, MENU_ADD_PICTURE, 0, R.string.add_picture).setIcon(R.drawable.ic_menu_picture);
      menu.add(0, MENU_TAKE_PICTURE, 0, R.string.attach_take_photo)
          .setIcon(R.drawable.ic_menu_picture);
    }

    // Music
    if (slide.hasAudio()) {
      menu.add(0, MENU_DEL_AUDIO, 0, R.string.remove_music)
          .setIcon(R.drawable.ic_menu_remove_sound);
    } else if (!slide.hasVideo()) {
      if (MmsConfig.getAllowAttachAudio()) {
        SubMenu subMenu =
            menu.addSubMenu(0, MENU_SUB_AUDIO, 0, R.string.add_music)
                .setIcon(R.drawable.ic_menu_add_sound);
        subMenu.add(0, MENU_ADD_AUDIO, 0, R.string.attach_sound);
        subMenu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound);
      } else {
        menu.add(0, MENU_RECORD_SOUND, 0, R.string.attach_record_sound)
            .setIcon(R.drawable.ic_menu_add_sound);
      }
    }

    // Video
    if (slide.hasVideo()) {
      menu.add(0, MENU_DEL_VIDEO, 0, R.string.remove_video)
          .setIcon(R.drawable.ic_menu_remove_video);
    } else if (!slide.hasAudio() && !slide.hasImage()) {
      menu.add(0, MENU_ADD_VIDEO, 0, R.string.add_video).setIcon(R.drawable.ic_menu_movie);
      menu.add(0, MENU_TAKE_VIDEO, 0, R.string.attach_record_video)
          .setIcon(R.drawable.ic_menu_movie);
    }

    // Add slide
    menu.add(0, MENU_ADD_SLIDE, 0, R.string.add_slide).setIcon(R.drawable.ic_menu_add_slide);

    // Slide duration
    String duration = getResources().getString(R.string.duration_sec);
    menu.add(
            0, MENU_DURATION, 0, duration.replace("%s", String.valueOf(slide.getDuration() / 1000)))
        .setIcon(R.drawable.ic_menu_duration);

    // Slide layout
    int resId;
    if (mSlideshowModel.getLayout().getLayoutType() == LayoutModel.LAYOUT_TOP_TEXT) {
      resId = R.string.layout_top;
    } else {
      resId = R.string.layout_bottom;
    }
    // FIXME: set correct icon when layout icon is available.
    menu.add(0, MENU_LAYOUT, 0, resId).setIcon(R.drawable.ic_menu_picture);
    return true;
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit_slide_activity);

    mSlideView = (BasicSlideEditorView) findViewById(R.id.slide_editor_view);
    mSlideView.setOnTextChangedListener(mOnTextChangedListener);

    mPreSlide = (ImageButton) findViewById(R.id.pre_slide_button);
    mPreSlide.setOnClickListener(mOnNavigateBackward);

    mNextSlide = (ImageButton) findViewById(R.id.next_slide_button);
    mNextSlide.setOnClickListener(mOnNavigateForward);

    mPreview = (Button) findViewById(R.id.preview_button);
    mPreview.setOnClickListener(mOnPreview);

    mReplaceImage = (Button) findViewById(R.id.replace_image_button);
    mReplaceImage.setOnClickListener(mOnReplaceImage);

    mRemoveSlide = (Button) findViewById(R.id.remove_slide_button);
    mRemoveSlide.setOnClickListener(mOnRemoveSlide);

    mTextEditor = (EditText) findViewById(R.id.text_message);
    mTextEditor.setFilters(new InputFilter[] {new LengthFilter(MmsConfig.getMaxTextLimit())});

    mDone = (Button) findViewById(R.id.done_button);
    mDone.setOnClickListener(mDoneClickListener);

    initActivityState(savedInstanceState, getIntent());

    try {
      mSlideshowModel = SlideshowModel.createFromMessageUri(this, mUri);
      // Confirm that we have at least 1 slide to display
      if (mSlideshowModel.size() == 0) {
        Log.e(TAG, "Loaded slideshow is empty; can't edit nothingness, exiting.");
        finish();
        return;
      }
      // Register an observer to watch whether the data model is changed.
      mSlideshowModel.registerModelChangedObserver(mModelChangedObserver);
      mSlideshowEditor = new SlideshowEditor(this, mSlideshowModel);
      mPresenter =
          (SlideshowPresenter)
              PresenterFactory.getPresenter(
                  "SlideshowPresenter", this, mSlideView, mSlideshowModel);

      // Sanitize mPosition
      if (mPosition >= mSlideshowModel.size()) {
        mPosition = Math.max(0, mSlideshowModel.size() - 1);
      } else if (mPosition < 0) {
        mPosition = 0;
      }

      showCurrentSlide();
    } catch (MmsException e) {
      Log.e(TAG, "Create SlideshowModel failed!", e);
      finish();
      return;
    }
  }
  @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);
    }
  }
  /**
   * A helper method to send or retrieve data through HTTP protocol.
   *
   * @param token The token to identify the sending progress.
   * @param url The URL used in a GET request. Null when the method is HTTP_POST_METHOD.
   * @param pdu The data to be POST. Null when the method is HTTP_GET_METHOD.
   * @param method HTTP_POST_METHOD or HTTP_GET_METHOD.
   * @return A byte array which contains the response data. If an HTTP error code is returned, an
   *     IOException will be thrown.
   * @throws IOException if any error occurred on network interface or an HTTP error code(&gt;=400)
   *     returned from the server.
   */
  protected static byte[] httpConnection(
      Context context,
      long token,
      String url,
      byte[] pdu,
      int method,
      boolean isProxySet,
      String proxyHost,
      int proxyPort)
      throws IOException {
    if (url == null) {
      throw new IllegalArgumentException("URL must not be null.");
    }

    if (LOCAL_LOGV) {
      Log.v(TAG, "httpConnection: params list");
      Log.v(TAG, "\ttoken\t\t= " + token);
      Log.v(TAG, "\turl\t\t= " + url);
      Log.v(TAG, "\tUser-Agent\t\t=" + mUserAgent);
      Log.v(
          TAG,
          "\tmethod\t\t= "
              + ((method == HTTP_POST_METHOD)
                  ? "POST"
                  : ((method == HTTP_GET_METHOD) ? "GET" : "UNKNOWN")));
      Log.v(TAG, "\tisProxySet\t= " + isProxySet);
      Log.v(TAG, "\tproxyHost\t= " + proxyHost);
      Log.v(TAG, "\tproxyPort\t= " + proxyPort);
      // TODO Print out binary data more readable.
      // Log.v(TAG, "\tpdu\t\t= " + Arrays.toString(pdu));
    }

    AndroidHttpClient client = null;

    try {
      // Make sure to use a proxy which supports CONNECT.
      URI hostUrl = new URI(url);
      HttpHost target =
          new HttpHost(hostUrl.getHost(), hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);

      client = createHttpClient(context);
      HttpRequest req = null;
      switch (method) {
        case HTTP_POST_METHOD:
          ProgressCallbackEntity entity = new ProgressCallbackEntity(context, token, pdu);
          // Set request content type.
          entity.setContentType("application/vnd.wap.mms-message");

          HttpPost post = new HttpPost(url);
          post.setEntity(entity);
          req = post;
          break;
        case HTTP_GET_METHOD:
          req = new HttpGet(url);
          break;
        default:
          Log.e(
              TAG,
              "Unknown HTTP method: "
                  + method
                  + ". Must be one of POST["
                  + HTTP_POST_METHOD
                  + "] or GET["
                  + HTTP_GET_METHOD
                  + "].");
          return null;
      }

      // Set route parameters for the request.
      HttpParams params = client.getParams();
      if (isProxySet) {
        ConnRouteParams.setDefaultProxy(params, new HttpHost(proxyHost, proxyPort));
      }
      req.setParams(params);

      // Set necessary HTTP headers for MMS transmission.
      req.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);
      {
        String xWapProfileTagName = MmsConfig.getUaProfTagName();
        String xWapProfileUrl = MmsConfig.getUaProfUrl();

        if (xWapProfileUrl != null) {
          if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) {
            Log.d(LogTag.TRANSACTION, "[HttpUtils] httpConn: xWapProfUrl=" + xWapProfileUrl);
          }
          req.addHeader(xWapProfileTagName, xWapProfileUrl);
        }
      }

      // Extra http parameters. Split by '|' to get a list of value pairs.
      // Separate each pair by the first occurrence of ':' to obtain a name and
      // value. Replace the occurrence of the string returned by
      // MmsConfig.getHttpParamsLine1Key() with the users telephone number inside
      // the value.
      String extraHttpParams = MmsConfig.getHttpParams();

      if (extraHttpParams != null) {
        String line1Number =
            ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
                .getLine1Number();
        String line1Key = MmsConfig.getHttpParamsLine1Key();
        String paramList[] = extraHttpParams.split("\\|");

        for (String paramPair : paramList) {
          String splitPair[] = paramPair.split(":", 2);

          if (splitPair.length == 2) {
            String name = splitPair[0].trim();
            String value = splitPair[1].trim();

            if (line1Key != null) {
              value = value.replace(line1Key, line1Number);
            }
            if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) {
              req.addHeader(name, value);
            }
          }
        }
      }
      req.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);

      HttpResponse response = client.execute(target, req);
      StatusLine status = response.getStatusLine();
      if (status.getStatusCode() != 200) { // HTTP 200 is success.
        throw new IOException("HTTP error: " + status.getReasonPhrase());
      }

      HttpEntity entity = response.getEntity();
      byte[] body = null;
      if (entity != null) {
        try {
          if (entity.getContentLength() > 0) {
            body = new byte[(int) entity.getContentLength()];
            DataInputStream dis = new DataInputStream(entity.getContent());
            try {
              dis.readFully(body);
            } finally {
              try {
                dis.close();
              } catch (IOException e) {
                Log.e(TAG, "Error closing input stream: " + e.getMessage());
              }
            }
          }
        } finally {
          if (entity != null) {
            entity.consumeContent();
          }
        }
      }
      return body;
    } catch (URISyntaxException e) {
      handleHttpConnectionException(e, url);
    } catch (IllegalStateException e) {
      handleHttpConnectionException(e, url);
    } catch (IllegalArgumentException e) {
      handleHttpConnectionException(e, url);
    } catch (SocketException e) {
      handleHttpConnectionException(e, url);
    } catch (Exception e) {
      handleHttpConnectionException(e, url);
    } finally {
      if (client != null) {
        client.close();
      }
    }
    return null;
  }
示例#9
0
  private List<Map<String, Object>> getSimData() {
    List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
    Map<String, Object> map = new HashMap<String, Object>();
    Resources res = getResources();
    int msimindex = MmsConfig.getSimCardInfo();
    if (msimindex > mSubCount) {
      msimindex = msimindex - 1;
    }
    map.put(VIEW_ITEM_KEY_SIMNAME, res.getText(R.string.allmessage));
    if (msimindex == 0) {
      map.put(VIEW_ITEM_KEY_SELECT, true);
    } else {
      map.put(VIEW_ITEM_KEY_SELECT, false);
    }
    map.put(VIEW_ITEM_KEY, "0");

    list.add(map);
    if (mSubCount == 2) {
      map = new HashMap<String, Object>();
      if (mSubInfoList.get(0).slotId == 0) {
        map.put(VIEW_ITEM_KEY_IMAGE, mSubInfoList.get(0).simIconRes[0]);
        map.put(VIEW_ITEM_KEY_SIMNAME, mSubInfoList.get(0).displayName);
      } else {
        map.put(VIEW_ITEM_KEY_IMAGE, mSubInfoList.get(1).simIconRes[0]);
        map.put(VIEW_ITEM_KEY_SIMNAME, mSubInfoList.get(1).displayName);
      }
      if (msimindex == 1) {
        map.put(VIEW_ITEM_KEY_SELECT, true);
      } else {
        map.put(VIEW_ITEM_KEY_SELECT, false);
      }
      map.put(VIEW_ITEM_KEY, "1");
      list.add(map);

      map = new HashMap<String, Object>();
      if (mSubInfoList.get(0).slotId == 1) {
        map.put(VIEW_ITEM_KEY_IMAGE, mSubInfoList.get(0).simIconRes[0]);
        map.put(VIEW_ITEM_KEY_SIMNAME, mSubInfoList.get(0).displayName);
      } else {
        map.put(VIEW_ITEM_KEY_IMAGE, mSubInfoList.get(1).simIconRes[0]);
        map.put(VIEW_ITEM_KEY_SIMNAME, mSubInfoList.get(1).displayName);
      }
      if (msimindex == 2) {
        map.put(VIEW_ITEM_KEY_SELECT, true);
      } else {
        map.put(VIEW_ITEM_KEY_SELECT, false);
      }
      map.put(VIEW_ITEM_KEY, "2");
      list.add(map);
    } else if (mSubCount == 1) {
      int slotId = 0;
      if (FeatureOption.MTK_GEMINI_SUPPORT) {
        map = new HashMap<String, Object>();
        map.put(VIEW_ITEM_KEY_IMAGE, mSubInfoList.get(0).simIconRes[0]);
        map.put(VIEW_ITEM_KEY_SIMNAME, mSubInfoList.get(0).displayName);
        if (msimindex == 1) {
          map.put(VIEW_ITEM_KEY_SELECT, true);
        } else {
          map.put(VIEW_ITEM_KEY_SELECT, false);
        }
        map.put(VIEW_ITEM_KEY, "1");
        list.add(map);
      }
    }
    return list;
  }
  @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();
    }
    /// @}
  }
    @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;
    }