content: package com.klinker.android.send_message;
  
  import android.app.AlertDialog;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.SharedPreferences;
  import android.content.res.XmlResourceParser;
  import android.os.Build;
  import android.preference.PreferenceManager;
  import android.telephony.ServiceState;
  import android.telephony.TelephonyManager;
  import android.telephony.cdma.CdmaCellLocation;
  import android.widget.Toast;
  
  import com.klinker.android.logger.Log;
  
  import org.xmlpull.v1.XmlPullParser;
  import org.xmlpull.v1.XmlPullParserException;
  
  import java.io.IOException;
  import java.util.ArrayList;
  
  public class ApnUtils {
  
      private static final String TAG = "ApnUtils";
  
      public static void initDefaultApns(final Context context, final OnApnFinishedListener listener) {
          loadMmsSettings(context);
          final ArrayList<APN> apns = loadApns(context);
  
          if (apns == null || apns.size() == 0) {
              Log.v(TAG, "Found no APNs :( Damn CDMA network probably.");
              Toast.makeText(context, context.getString(R.string.auto_select_failed), Toast.LENGTH_SHORT).show();
              if (listener != null) {
                  listener.onFinished();
              }
          } else if (apns.size() == 1) {
              setApns(context, apns.get(0));
              if (listener != null) {
                  listener.onFinished();
              }
          } else {
              if (!PreferenceManager.getDefaultSharedPreferences(context).getBoolean("has_seen_select_apns_warning", false)) {
                  new AlertDialog.Builder(context)
                          .setTitle(R.string.auto_select_apn)
                          .setMessage(R.string.auto_select_multiple_apns)
                          .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                              @Override
                              public void onClick(DialogInterface dialogInterface, int num) {
                                  showApnChooser(context, apns, listener);
                              }
                          })
                          .show();
                  PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean("has_seen_select_apns_warning", true).commit();
              } else {
                  showApnChooser(context, apns, listener);
              }
          }
      }
  
      private static void showApnChooser(final Context context, final ArrayList<APN> apns, final OnApnFinishedListener listener) {
          CharSequence[] items = new CharSequence[apns.size()];
          SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
          String curMmsc = sharedPrefs.getString("mmsc_url", "");
          String curProxy = sharedPrefs.getString("mms_proxy", "");
          String curPort = sharedPrefs.getString("mms_port", "");
  
          int defaultApn = -1;
          for (int i = 0; i < items.length; i++) {
              APN apn = apns.get(i);
              items[i] = (i+1) + ". " + apn.name;
  
              if (apn.mmsc.equals(curMmsc) && apn.proxy.equals(curProxy) && apn.port.equals(curPort)) {
                  defaultApn = i;
              }
          }
  
          new AlertDialog.Builder(context)
                  .setSingleChoiceItems(items, defaultApn, new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialogInterface, int i) {
                          setApns(context, apns.get(i));
                          if (listener != null) {
                              listener.onFinished();
                          }
                          dialogInterface.dismiss();
                      }
                  })
                  .setOnCancelListener(new DialogInterface.OnCancelListener() {
                      @Override
                      public void onCancel(DialogInterface dialogInterface) {
                          if (listener != null) {
                              listener.onFinished();
                          }
                      }
                  })
                  .show();
      }
  
      public interface OnApnFinishedListener {
          public abstract void onFinished();
      }
  
      private static void loadMmsSettings(Context context) {
          XmlResourceParser parser = context.getResources().getXml(R.xml.mms_config);
          String maxMessageSize = 1000000 + "";
          int maxImageHeight = 800;
          int maxImageWidth = 800;
          String userAgent = "Android Messaging";
          String uaProfUrl = "http://www.gstatic.com/android/hangouts/hangouts_mms_ua_profile.xml";
  
          try {
              beginDocument(parser, "mms_config");
  
              while (true) {
                  nextElement(parser);
                  String tag = parser.getName();
                  if (tag == null) {
                      break;
                  }
                  String name = parser.getAttributeName(0);
                  String value = parser.getAttributeValue(0);
                  String text = null;
                  if (parser.next() == XmlPullParser.TEXT) {
                      text = parser.getText();
                  }
  
                  Log.v(TAG, "tag: " + tag + " value: " + value + " - " +
                          text);
                  if ("name".equalsIgnoreCase(name)) {
                      if ("int".equals(tag)) {
                          // int config tags go here
                          if ("maxMessageSize".equalsIgnoreCase(value)) {
                              maxMessageSize = text;
                          } else if ("maxImageHeight".equalsIgnoreCase(value)) {
                              maxImageHeight = Integer.parseInt(text);
                          } else if ("maxImageWidth".equalsIgnoreCase(value)) {
                              maxImageWidth = Integer.parseInt(text);
                          }
                      } else if ("string".equals(tag)) {
                          // string config tags go here
                          if ("userAgent".equalsIgnoreCase(value)) {
                              userAgent = text;
                          } else if ("uaProfUrl".equalsIgnoreCase(value)) {
                              uaProfUrl = text;
                          }
                      }
                  }
              }
          } catch (XmlPullParserException e) {
              Log.e(TAG, "loadMmsSettings caught ", e);
          } catch (NumberFormatException e) {
              Log.e(TAG, "loadMmsSettings caught ", e);
          } catch (IOException e) {
              Log.e(TAG, "loadMmsSettings caught ", e);
          } finally {
              parser.close();
          }
  
          String errorStr = null;
  
          if (errorStr != null) {
              String err =
                      String.format("MmsConfig.loadMmsSettings mms_config.xml missing %s setting",
                              errorStr);
              Log.e(TAG, err);
          }
  
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
              final TelephonyManager telephonyManager =
                      (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
              userAgent = telephonyManager.getMmsUserAgent();
              uaProfUrl = telephonyManager.getMmsUAProfUrl();
          }
  
          PreferenceManager.getDefaultSharedPreferences(context)
                  .edit()
                  .putInt("mms_max_width", maxImageWidth)
                  .putInt("mms_max_height", maxImageHeight)
                  .putString("mms_max_size", maxMessageSize)
                  .putString("mms_agent", userAgent)
                  .putString("mms_user_agent_profile_url", uaProfUrl)
                  .commit();
      }
  
      private static ArrayList<APN> loadApns(Context context) {
          XmlResourceParser parser = context.getResources().getXml(R.xml.apns);
          ArrayList<APN> apns = new ArrayList<APN>();
          String mmsc = "", proxy = "", port = "", carrier = "";
  
          int mcc = -1, mnc = -1;
  
          TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
          String networkOperator = manager.getNetworkOperator();
  
          if (isValidNetworkOperator(networkOperator)) {
              mcc = Integer.parseInt(networkOperator.substring(0, 3));
              String s = networkOperator.substring(3);
              try {
                  mnc = Integer.parseInt(s.replaceFirst("^0{1,2}", ""));
              } catch (Exception e) {
                  mnc = -1;
              }
          } else {
              mcc = context.getResources().getConfiguration().mcc;
              mnc = context.getResources().getConfiguration().mnc;
          }
  
          try {
              if (mcc == -1) {
                  mcc = Integer.parseInt(new ServiceState().getOperatorNumeric().substring(0, 3));
              }
  
              if (mnc == -1) {
                  TelephonyManager tm  = (TelephonyManager) context.getSystemService
                          (Context.TELEPHONY_SERVICE);
                  mnc = ((CdmaCellLocation) tm.getCellLocation()).getSystemId();
              }
          } catch (Exception e) {
  
          }
  
          if (mcc == -1 || mnc == -1) {
              Log.v(TAG, "couldn't find both mcc and mnc. mcc = " + mcc + ", mnc = " + mnc);
              return null;
          }
  
          Log.v(TAG, "mcc: " + mcc + " mnc: " + mnc);
  
          try {
              beginDocument(parser, "apns");
  
              while (true) {
                  nextElement(parser);
                  String tag = parser.getName();
                  if (tag == null) {
                      break;
                  }
  
                  boolean mccCorrect = false, mncCorrect = false;
                  for (int i = 0; i < parser.getAttributeCount(); i++) {
                      try {
                          String name = parser.getAttributeName(i);
                          int value = Integer.parseInt(parser.getAttributeValue(i));
                          if ("mcc".equals(name) && mcc == value) {
                              mccCorrect = true;
                          } else if ("mnc".equals(name) && mnc == value) {
                              mncCorrect = true;
                          }
                      } catch (Exception e) {
                          // cast exception probably
                      }
                  }
  
                  if (mccCorrect && mncCorrect) {
                      // parse the rest of the apn
                      for (int i = 0; i < parser.getAttributeCount(); i++) {
                          String name = parser.getAttributeName(i);
                          String value = parser.getAttributeValue(i);
                          if ("type".equals(name)) {
                              if (!value.contains("mms")) {
                                  mmsc = "";
                                  proxy = "";
                                  port = "";
                                  break;
                              }
                          } else if ("mmsc".equals(name)) {
                              mmsc = value;
                          } else if ("mmsproxy".equals(name)) {
                              proxy = value;
                          } else if ("mmsport".equals(name)) {
                              port = value;
                          } else if ("carrier".equals(name)) {
                              carrier = value;
                          } else if ("port".equals(name) && port.equals("")) {
                              port = value;
                          }
                      }
  
                      if (!mmsc.equals("")) {
                          APN apn = new APN();
                          apn.name = carrier;
                          apn.mmsc = mmsc;
                          apn.proxy = proxy;
                          apn.port = port;
  
                          boolean contains = false;
                          for (int i = 0; i < apns.size(); i++) {
                              APN current = apns.get(i);
  
                              if (current.mmsc.equals(apn.mmsc) && current.port.equals(apn.port) && current.proxy.equals(apn.proxy)) {
                                  contains = true;
                                  break;
                              }
                          }
  
                          if (!contains) {
                              apns.add(apn);
                          }
                      }
                  }
              }
          } catch (XmlPullParserException e) {
              Log.e(TAG, "loadApns caught ", e);
          } catch (NumberFormatException e) {
              Log.e(TAG, "loadApns caught ", e);
          } catch (IOException e) {
              Log.e(TAG, "loadApns caught ", e);
          } finally {
              parser.close();
          }
  
          Log.v(TAG, "MMSC: " + mmsc + ", MMS Proxy: " + proxy + ", MMS Port: " + port);
  
          String errorStr = null;
  
          if (errorStr != null) {
              String err =
                      String.format("MmsConfig.loadMmsSettings mms_config.xml missing %s setting",
                              errorStr);
              Log.e(TAG, err);
          }
  
          return apns;
      }
  
      /**
       * Checks if the given network operator is valid, i.e. it's not null, empty or contains "null"
       *
       * @param networkOperator
       *         The network operator to be checked
       *
       * @return True if is a valid operator
       */
      private static boolean isValidNetworkOperator(String networkOperator) {
        return networkOperator != null && !networkOperator.isEmpty() &&
                !networkOperator.contains("null");
      }
  
      private static void setApns(Context context, APN apn) {
          PreferenceManager.getDefaultSharedPreferences(context)
                  .edit()
                  .putString("mmsc_url", apn.mmsc)
                  .putString("mms_proxy", apn.proxy)
                  .putString("mms_port", apn.port)
                  .commit();
      }
  
      private static void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException {
          int type;
          while ((type=parser.next()) != parser.START_TAG
                  && type != parser.END_DOCUMENT) {
              ;
          }
  
          if (type != parser.START_TAG) {
              throw new XmlPullParserException("No start tag found");
          }
  
          if (!parser.getName().equals(firstElementName)) {
              throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
                      ", expected " + firstElementName);
          }
      }
  
      private static void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException {
          int type;
          while ((type=parser.next()) != parser.START_TAG
                  && type != parser.END_DOCUMENT) {
              ;
          }
      }
  
      private static class APN {
          public String name;
          public String mmsc;
          public String proxy;
          public String port;
      }
  }
  