From 861b4bf9c957ce094724297f9aebdcb38fd20d4f Mon Sep 17 00:00:00 2001
From: Ryan ZHAO <ryanzhaors@qq.com>
Date: Mon, 22 Feb 2021 16:54:57 +1100
Subject: [PATCH] further clean up unused connections

---
 .../securesms/database/ApnDatabase.java       | 174 ----------
 .../mms/IncomingLollipopMmsConnection.java    | 121 -------
 .../securesms/mms/IncomingMmsConnection.java  |  13 -
 .../securesms/mms/LegacyMmsConnection.java    | 314 ------------------
 .../securesms/mms/LollipopMmsConnection.java  |  86 -----
 .../mms/OutgoingLollipopMmsConnection.java    | 115 -------
 .../securesms/mms/OutgoingMmsConnection.java  |  14 -
 7 files changed, 837 deletions(-)
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/ApnDatabase.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/LegacyMmsConnection.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/LollipopMmsConnection.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java
 delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java

diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/ApnDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/ApnDatabase.java
deleted file mode 100644
index 94c2e4c0d0..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/database/ApnDatabase.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * Copyright (C) 2014 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.thoughtcrime.securesms.database;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteException;
-import android.text.TextUtils;
-import org.session.libsignal.utilities.logging.Log;
-
-import org.thoughtcrime.securesms.mms.LegacyMmsConnection.Apn;
-import org.session.libsession.utilities.TextSecurePreferences;
-import org.session.libsession.utilities.Util;
-import org.session.libsignal.libsignal.util.guava.Optional;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Database to query APN and MMSC information
- */
-public class ApnDatabase {
-  private static final String TAG = ApnDatabase.class.getSimpleName();
-
-  private final SQLiteDatabase db;
-  private final Context        context;
-
-  private static final String DATABASE_NAME = "apns.db";
-  private static final String ASSET_PATH    = "databases" + File.separator + DATABASE_NAME;
-
-  private static final String TABLE_NAME              = "apns";
-  private static final String ID_COLUMN               = "_id";
-  private static final String MCC_MNC_COLUMN          = "mccmnc";
-  private static final String MCC_COLUMN              = "mcc";
-  private static final String MNC_COLUMN              = "mnc";
-  private static final String CARRIER_COLUMN          = "carrier";
-  private static final String APN_COLUMN              = "apn";
-  private static final String MMSC_COLUMN             = "mmsc";
-  private static final String PORT_COLUMN             = "port";
-  private static final String TYPE_COLUMN             = "type";
-  private static final String PROTOCOL_COLUMN         = "protocol";
-  private static final String BEARER_COLUMN           = "bearer";
-  private static final String ROAMING_PROTOCOL_COLUMN = "roaming_protocol";
-  private static final String CARRIER_ENABLED_COLUMN  = "carrier_enabled";
-  private static final String MMS_PROXY_COLUMN        = "mmsproxy";
-  private static final String MMS_PORT_COLUMN         = "mmsport";
-  private static final String PROXY_COLUMN            = "proxy";
-  private static final String MVNO_MATCH_DATA_COLUMN  = "mvno_match_data";
-  private static final String MVNO_TYPE_COLUMN        = "mvno";
-  private static final String AUTH_TYPE_COLUMN        = "authtype";
-  private static final String USER_COLUMN             = "user";
-  private static final String PASSWORD_COLUMN         = "password";
-  private static final String SERVER_COLUMN           = "server";
-
-  private static final String BASE_SELECTION = MCC_MNC_COLUMN + " = ?";
-
-  private static ApnDatabase instance = null;
-
-  public synchronized static ApnDatabase getInstance(Context context) throws IOException {
-    if (instance == null) instance = new ApnDatabase(context.getApplicationContext());
-    return instance;
-  }
-
-  private ApnDatabase(final Context context) throws IOException {
-    this.context = context;
-
-    File dbFile = context.getDatabasePath(DATABASE_NAME);
-
-    if (!dbFile.getParentFile().exists() && !dbFile.getParentFile().mkdir()) {
-      throw new IOException("couldn't make databases directory");
-    }
-
-    Util.copy(context.getAssets().open(ASSET_PATH, AssetManager.ACCESS_STREAMING),
-              new FileOutputStream(dbFile));
-
-    try {
-      this.db = SQLiteDatabase.openDatabase(context.getDatabasePath(DATABASE_NAME).getPath(),
-                                            null,
-                                            SQLiteDatabase.OPEN_READONLY | SQLiteDatabase.NO_LOCALIZED_COLLATORS);
-    } catch (SQLiteException e) {
-      throw new IOException(e);
-    }
-  }
-
-  private Apn getCustomApnParameters() {
-      String mmsc = TextSecurePreferences.getMmscUrl(context).trim();
-
-      if (!TextUtils.isEmpty(mmsc) && !mmsc.startsWith("http"))
-        mmsc = "http://" + mmsc;
-
-      String proxy = TextSecurePreferences.getMmscProxy(context);
-      String port  = TextSecurePreferences.getMmscProxyPort(context);
-      String user  = TextSecurePreferences.getMmscUsername(context);
-      String pass  = TextSecurePreferences.getMmscPassword(context);
-
-      return new Apn(mmsc, proxy, port, user, pass);
-  }
-
-  public Apn getDefaultApnParameters(String mccmnc, String apn) {
-    if (mccmnc == null) {
-      Log.w(TAG, "mccmnc was null, returning null");
-      return Apn.EMPTY;
-    }
-
-    Cursor cursor = null;
-
-    try {
-      if (apn != null) {
-        Log.d(TAG, "Querying table for MCC+MNC " + mccmnc + " and APN name " + apn);
-        cursor = db.query(TABLE_NAME, null,
-                          BASE_SELECTION + " AND " + APN_COLUMN + " = ?",
-                          new String[] {mccmnc, apn},
-                          null, null, null);
-      }
-
-      if (cursor == null || !cursor.moveToFirst()) {
-        if (cursor != null) cursor.close();
-        Log.d(TAG, "Querying table for MCC+MNC " + mccmnc + " without APN name");
-        cursor = db.query(TABLE_NAME, null,
-                          BASE_SELECTION,
-                          new String[] {mccmnc},
-                          null, null, null);
-      }
-
-      if (cursor != null && cursor.moveToFirst()) {
-        Apn params = new Apn(cursor.getString(cursor.getColumnIndexOrThrow(MMSC_COLUMN)),
-                             cursor.getString(cursor.getColumnIndexOrThrow(MMS_PROXY_COLUMN)),
-                             cursor.getString(cursor.getColumnIndexOrThrow(MMS_PORT_COLUMN)),
-                             cursor.getString(cursor.getColumnIndexOrThrow(USER_COLUMN)),
-                             cursor.getString(cursor.getColumnIndexOrThrow(PASSWORD_COLUMN)));
-        Log.d(TAG, "Returning preferred APN " + params);
-        return params;
-      }
-
-      Log.w(TAG, "No matching APNs found, returning null");
-
-      return Apn.EMPTY;
-    } finally {
-      if (cursor != null) cursor.close();
-    }
-
-  }
-
-  public Optional<Apn> getMmsConnectionParameters(String mccmnc, String apn) {
-    Apn customApn  = getCustomApnParameters();
-    Apn defaultApn = getDefaultApnParameters(mccmnc, apn);
-    Apn result     = new Apn(customApn, defaultApn,
-                             TextSecurePreferences.getUseCustomMmsc(context),
-                             TextSecurePreferences.getUseCustomMmscProxy(context),
-                             TextSecurePreferences.getUseCustomMmscProxyPort(context),
-                             TextSecurePreferences.getUseCustomMmscUsername(context),
-                             TextSecurePreferences.getUseCustomMmscPassword(context));
-
-    if (TextUtils.isEmpty(result.getMmsc())) return Optional.absent();
-    else                                     return Optional.of(result);
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java
deleted file mode 100644
index 2159c38ecc..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingLollipopMmsConnection.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright (C) 2015 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.thoughtcrime.securesms.mms;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import android.telephony.SmsManager;
-import org.session.libsignal.utilities.logging.Log;
-
-import com.google.android.mms.InvalidHeaderValueException;
-import com.google.android.mms.pdu_alt.NotifyRespInd;
-import com.google.android.mms.pdu_alt.PduComposer;
-import com.google.android.mms.pdu_alt.PduHeaders;
-import com.google.android.mms.pdu_alt.PduParser;
-import com.google.android.mms.pdu_alt.RetrieveConf;
-
-import org.thoughtcrime.securesms.providers.MmsBodyProvider;
-import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
-import org.session.libsession.utilities.Util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-public class IncomingLollipopMmsConnection extends LollipopMmsConnection implements IncomingMmsConnection {
-
-  public  static final String ACTION = IncomingLollipopMmsConnection.class.getCanonicalName() + "MMS_DOWNLOADED_ACTION";
-  private static final String TAG    = IncomingLollipopMmsConnection.class.getSimpleName();
-
-  public IncomingLollipopMmsConnection(Context context) {
-    super(context, ACTION);
-  }
-
-  @TargetApi(VERSION_CODES.LOLLIPOP)
-  @Override
-  public synchronized void onResult(Context context, Intent intent) {
-    if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP_MR1) {
-      Log.i(TAG, "HTTP status: " + intent.getIntExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, -1));
-    }
-    Log.i(TAG, "code: " + getResultCode() + ", result string: " + getResultData());
-  }
-
-  @Override
-  @TargetApi(VERSION_CODES.LOLLIPOP)
-  public synchronized @Nullable RetrieveConf retrieve(@NonNull String contentLocation,
-                                                      byte[] transactionId,
-                                                      int subscriptionId) throws MmsException
-  {
-    beginTransaction();
-
-    try {
-      MmsBodyProvider.Pointer pointer = MmsBodyProvider.makeTemporaryPointer(getContext());
-
-      Log.i(TAG, "downloading multimedia from " + contentLocation + " to " + pointer.getUri());
-
-      SmsManager smsManager;
-
-      if (VERSION.SDK_INT >= 22 && subscriptionId != -1) {
-        smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
-      } else {
-        smsManager = SmsManager.getDefault();
-      }
-
-      smsManager.downloadMultimediaMessage(getContext(),
-                                           contentLocation,
-                                           pointer.getUri(),
-                                           null,
-                                           getPendingIntent());
-
-      waitForResult();
-
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      Util.copy(pointer.getInputStream(), baos);
-      pointer.close();
-
-      Log.i(TAG, baos.size() + "-byte response: ");// + Hex.dump(baos.toByteArray()));
-
-      RetrieveConf retrieved = (RetrieveConf) new PduParser(baos.toByteArray()).parse();
-
-      if (retrieved == null) return null;
-
-      sendRetrievedAcknowledgement(transactionId, retrieved.getMmsVersion(), subscriptionId);
-      return retrieved;
-    } catch (IOException | TimeoutException e) {
-      Log.w(TAG, e);
-      throw new MmsException(e);
-    } finally {
-      endTransaction();
-    }
-  }
-
-  private void sendRetrievedAcknowledgement(byte[] transactionId, int mmsVersion, int subscriptionId) {
-    try {
-      NotifyRespInd retrieveResponse = new NotifyRespInd(mmsVersion, transactionId, PduHeaders.STATUS_RETRIEVED);
-      new OutgoingLollipopMmsConnection(getContext()).send(new PduComposer(getContext(), retrieveResponse).make(), subscriptionId);
-    } catch (UndeliverableMessageException e) {
-      Log.w(TAG, e);
-    } catch (InvalidHeaderValueException e) {
-      Log.w(TAG, e);
-    }
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java
deleted file mode 100644
index 44827068fd..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/IncomingMmsConnection.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package org.thoughtcrime.securesms.mms;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.android.mms.pdu_alt.RetrieveConf;
-
-import java.io.IOException;
-
-public interface IncomingMmsConnection {
-  @Nullable
-  RetrieveConf retrieve(@NonNull String contentLocation, byte[] transactionId, int subscriptionId) throws MmsException, MmsRadioException, ApnUnavailableException, IOException;
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/LegacyMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/LegacyMmsConnection.java
deleted file mode 100644
index 359c4ef8ba..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/LegacyMmsConnection.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- * Copyright (C) 2011 Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.thoughtcrime.securesms.mms;
-
-import android.Manifest;
-import android.annotation.SuppressLint;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import androidx.annotation.NonNull;
-import androidx.core.app.ActivityCompat;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import org.session.libsignal.utilities.logging.Log;
-
-import org.apache.http.Header;
-import org.apache.http.auth.AuthScope;
-import org.apache.http.auth.UsernamePasswordCredentials;
-import org.apache.http.client.CredentialsProvider;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.impl.NoConnectionReuseStrategyHC4;
-import org.apache.http.impl.client.BasicCredentialsProvider;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.impl.client.LaxRedirectStrategy;
-import org.apache.http.impl.conn.BasicHttpClientConnectionManager;
-import org.apache.http.message.BasicHeader;
-import org.thoughtcrime.securesms.database.ApnDatabase;
-import org.session.libsession.utilities.ServiceUtil;
-import org.thoughtcrime.securesms.util.TelephonyUtil;
-import org.session.libsignal.libsignal.util.guava.Optional;
-
-import org.session.libsession.utilities.TextSecurePreferences;
-import org.session.libsession.utilities.Util;
-
-import java.io.BufferedInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.URL;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-@SuppressWarnings("deprecation")
-public abstract class LegacyMmsConnection {
-
-  public static final String USER_AGENT = "Android-Mms/2.0";
-
-  private static final String TAG = LegacyMmsConnection.class.getSimpleName();
-
-  protected final Context context;
-  protected final Apn     apn;
-
-  protected LegacyMmsConnection(Context context) throws ApnUnavailableException {
-    this.context = context;
-    this.apn     = getApn(context);
-  }
-
-  public static Apn getApn(Context context) throws ApnUnavailableException {
-
-    try {
-      Optional<Apn> params = ApnDatabase.getInstance(context)
-                                        .getMmsConnectionParameters(TelephonyUtil.getMccMnc(context),
-                                                                    TelephonyUtil.getApn(context));
-
-      if (!params.isPresent()) {
-        throw new ApnUnavailableException("No parameters available from ApnDefaults.");
-      }
-
-      return params.get();
-    } catch (IOException ioe) {
-      throw new ApnUnavailableException("ApnDatabase threw an IOException", ioe);
-    }
-  }
-
-  protected boolean isDirectConnect() {
-    // We think Sprint supports direct connection over wifi/data, but not Verizon
-    Set<String> sprintMccMncs = new HashSet<String>() {{
-      add("312530");
-      add("311880");
-      add("311870");
-      add("311490");
-      add("310120");
-      add("316010");
-      add("312190");
-    }};
-
-    return ServiceUtil.getTelephonyManager(context).getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA &&
-           sprintMccMncs.contains(TelephonyUtil.getMccMnc(context));
-  }
-
-  @SuppressWarnings("TryWithIdenticalCatches")
-  protected static boolean checkRouteToHost(Context context, String host, boolean usingMmsRadio)
-      throws IOException
-  {
-    InetAddress inetAddress = InetAddress.getByName(host);
-    if (!usingMmsRadio) {
-      if (inetAddress.isSiteLocalAddress()) {
-        throw new IOException("RFC1918 address in non-MMS radio situation!");
-      }
-      Log.w(TAG, "returning vacuous success since MMS radio is not in use");
-      return true;
-    }
-
-    if (inetAddress == null) {
-      throw new IOException("Unable to lookup host: InetAddress.getByName() returned null.");
-    }
-
-    byte[] ipAddressBytes = inetAddress.getAddress();
-    if (ipAddressBytes == null) {
-      Log.w(TAG, "resolved IP address bytes are null, returning true to attempt a connection anyway.");
-      return true;
-    }
-
-    Log.i(TAG, "Checking route to address: " + host + ", " + inetAddress.getHostAddress());
-    ConnectivityManager manager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-    try {
-      final Method  requestRouteMethod  = manager.getClass().getMethod("requestRouteToHostAddress", Integer.TYPE, InetAddress.class);
-      final boolean routeToHostObtained = (Boolean) requestRouteMethod.invoke(manager, MmsRadio.TYPE_MOBILE_MMS, inetAddress);
-      Log.i(TAG, "requestRouteToHostAddress(" + inetAddress + ") -> " + routeToHostObtained);
-      return routeToHostObtained;
-    } catch (NoSuchMethodException nsme) {
-      Log.w(TAG, nsme);
-    } catch (IllegalAccessException iae) {
-      Log.w(TAG, iae);
-    } catch (InvocationTargetException ite) {
-      Log.w(TAG, ite);
-    }
-
-    return false;
-  }
-
-  protected static byte[] parseResponse(InputStream is) throws IOException {
-    InputStream           in   = new BufferedInputStream(is);
-    ByteArrayOutputStream baos = new ByteArrayOutputStream();
-    Util.copy(in, baos);
-
-    Log.i(TAG, "Received full server response, " + baos.size() + " bytes");
-
-    return baos.toByteArray();
-  }
-
-  protected CloseableHttpClient constructHttpClient() throws IOException {
-    RequestConfig config = RequestConfig.custom()
-                                        .setConnectTimeout(20 * 1000)
-                                        .setConnectionRequestTimeout(20 * 1000)
-                                        .setSocketTimeout(20 * 1000)
-                                        .setMaxRedirects(20)
-                                        .build();
-
-    URL                 mmsc          = new URL(apn.getMmsc());
-    CredentialsProvider credsProvider = new BasicCredentialsProvider();
-
-    if (apn.hasAuthentication()) {
-      credsProvider.setCredentials(new AuthScope(mmsc.getHost(), mmsc.getPort() > -1 ? mmsc.getPort() : mmsc.getDefaultPort()),
-                                   new UsernamePasswordCredentials(apn.getUsername(), apn.getPassword()));
-    }
-
-    return HttpClients.custom()
-                      .setConnectionReuseStrategy(new NoConnectionReuseStrategyHC4())
-                      .setRedirectStrategy(new LaxRedirectStrategy())
-                      .setUserAgent(TextSecurePreferences.getMmsUserAgent(context, USER_AGENT))
-                      .setConnectionManager(new BasicHttpClientConnectionManager())
-                      .setDefaultRequestConfig(config)
-                      .setDefaultCredentialsProvider(credsProvider)
-                      .build();
-  }
-
-  protected byte[] execute(HttpUriRequest request) throws IOException {
-    Log.i(TAG, "connecting to " + apn.getMmsc());
-
-    CloseableHttpClient   client   = null;
-    CloseableHttpResponse response = null;
-    try {
-      client   = constructHttpClient();
-      response = client.execute(request);
-
-      Log.i(TAG, "* response code: " + response.getStatusLine());
-
-      if (response.getStatusLine().getStatusCode() == 200) {
-        return parseResponse(response.getEntity().getContent());
-      }
-    } catch (NullPointerException npe) {
-      // TODO determine root cause
-      // see: https://github.com/signalapp/Signal-Android/issues/4379
-      throw new IOException(npe);
-    } finally {
-      if (response != null) response.close();
-      if (client != null)   client.close();
-    }
-
-    throw new IOException("unhandled response code");
-  }
-
-  protected List<Header> getBaseHeaders() {
-    final String number = getLine1Number(context);
-
-    return new LinkedList<Header>() {{
-      add(new BasicHeader("Accept", "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"));
-      add(new BasicHeader("x-wap-profile", "http://www.google.com/oha/rdf/ua-profile-kila.xml"));
-      add(new BasicHeader("Content-Type", "application/vnd.wap.mms-message"));
-      add(new BasicHeader("x-carrier-magic", "http://magic.google.com"));
-      if (!TextUtils.isEmpty(number)) {
-        add(new BasicHeader("x-up-calling-line-id", number));
-        add(new BasicHeader("X-MDN", number));
-      }
-    }};
-  }
-
-  @SuppressLint("HardwareIds")
-  private static String getLine1Number(@NonNull Context context) {
-    if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_SMS)           == PackageManager.PERMISSION_GRANTED ||
-        ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_NUMBERS) == PackageManager.PERMISSION_GRANTED ||
-        ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)   == PackageManager.PERMISSION_GRANTED) {
-      return TelephonyUtil.getManager(context).getLine1Number();
-    } else {
-      return "";
-    }
-  }
-
-  public static class Apn {
-
-    public static Apn EMPTY = new Apn("", "", "", "", "");
-
-    private final String mmsc;
-    private final String proxy;
-    private final String port;
-    private final String username;
-    private final String password;
-
-    public Apn(String mmsc, String proxy, String port, String username, String password) {
-      this.mmsc     = mmsc;
-      this.proxy    = proxy;
-      this.port     = port;
-      this.username = username;
-      this.password = password;
-    }
-
-    public Apn(Apn customApn, Apn defaultApn,
-               boolean useCustomMmsc,
-               boolean useCustomProxy,
-               boolean useCustomProxyPort,
-               boolean useCustomUsername,
-               boolean useCustomPassword)
-    {
-      this.mmsc     = useCustomMmsc ? customApn.mmsc : defaultApn.mmsc;
-      this.proxy    = useCustomProxy ? customApn.proxy : defaultApn.proxy;
-      this.port     = useCustomProxyPort ? customApn.port : defaultApn.port;
-      this.username = useCustomUsername ? customApn.username : defaultApn.username;
-      this.password = useCustomPassword ? customApn.password : defaultApn.password;
-    }
-
-    public boolean hasProxy() {
-      return !TextUtils.isEmpty(proxy);
-    }
-
-    public String getMmsc() {
-      return mmsc;
-    }
-
-    public String getProxy() {
-      return hasProxy() ? proxy : null;
-    }
-
-    public int getPort() {
-      return TextUtils.isEmpty(port) ? 80 : Integer.parseInt(port);
-    }
-
-    public boolean hasAuthentication() {
-      return !TextUtils.isEmpty(username);
-    }
-
-    public String getUsername() {
-      return username;
-    }
-
-    public String getPassword() {
-      return password;
-    }
-
-    @Override
-    public @NonNull String toString() {
-      return Apn.class.getSimpleName() +
-          "{ mmsc: \"" + mmsc + "\"" +
-          ", proxy: " + (proxy == null ? "none" : '"' + proxy + '"') +
-          ", port: " + (port == null ? "(none)" : port) +
-          ", user: " + (username == null ? "none" : '"' + username + '"') +
-          ", pass: " + (password == null ? "none" : '"' + password + '"') + " }";
-    }
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/LollipopMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/LollipopMmsConnection.java
deleted file mode 100644
index bf9456782b..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/LollipopMmsConnection.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/**
- * Copyright (C) 2015 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.thoughtcrime.securesms.mms;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-
-import org.session.libsignal.utilities.logging.Log;
-import org.session.libsession.utilities.Util;
-
-import java.util.concurrent.TimeoutException;
-
-public abstract class LollipopMmsConnection extends BroadcastReceiver {
-  private static final String TAG = LollipopMmsConnection.class.getSimpleName();
-
-  private final Context context;
-  private final String action;
-
-  private boolean resultAvailable;
-
-  public abstract void onResult(Context context, Intent intent);
-
-  protected LollipopMmsConnection(Context context, String action) {
-    super();
-    this.context = context;
-    this.action  = action;
-  }
-
-  @Override
-  public synchronized void onReceive(Context context, Intent intent) {
-    Log.i(TAG, "onReceive()");
-    if (!action.equals(intent.getAction())) {
-      Log.w(TAG, "received broadcast with unexpected action " + intent.getAction());
-      return;
-    }
-
-    onResult(context, intent);
-
-    resultAvailable = true;
-    notifyAll();
-  }
-
-  protected void beginTransaction() {
-    getContext().getApplicationContext().registerReceiver(this, new IntentFilter(action));
-  }
-
-  protected void endTransaction() {
-    getContext().getApplicationContext().unregisterReceiver(this);
-    resultAvailable = false;
-  }
-
-  protected void waitForResult() throws TimeoutException {
-    long timeoutExpiration = System.currentTimeMillis() + 60000;
-    while (!resultAvailable) {
-      Util.wait(this, Math.max(1, timeoutExpiration - System.currentTimeMillis()));
-      if (System.currentTimeMillis() >= timeoutExpiration) {
-        throw new TimeoutException("timeout when waiting for MMS");
-      }
-    }
-  }
-
-  protected PendingIntent getPendingIntent() {
-    return PendingIntent.getBroadcast(getContext(), 1, new Intent(action), PendingIntent.FLAG_ONE_SHOT);
-  }
-
-  protected Context getContext() {
-    return context;
-  }
-}
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java
deleted file mode 100644
index fa851c2a09..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingLollipopMmsConnection.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * Copyright (C) 2015 Open Whisper Systems
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-package org.thoughtcrime.securesms.mms;
-
-import android.annotation.TargetApi;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Build.VERSION;
-import android.os.Build.VERSION_CODES;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import android.telephony.SmsManager;
-import org.session.libsignal.utilities.logging.Log;
-
-import com.android.mms.service_alt.MmsConfig;
-import com.google.android.mms.pdu_alt.PduParser;
-import com.google.android.mms.pdu_alt.SendConf;
-
-import org.thoughtcrime.securesms.providers.MmsBodyProvider;
-import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
-
-import org.session.libsession.utilities.Util;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.concurrent.TimeoutException;
-
-public class OutgoingLollipopMmsConnection extends LollipopMmsConnection implements OutgoingMmsConnection {
-  private static final String TAG    = OutgoingLollipopMmsConnection.class.getSimpleName();
-  private static final String ACTION = OutgoingLollipopMmsConnection.class.getCanonicalName() + "MMS_SENT_ACTION";
-
-  private byte[] response;
-
-  public OutgoingLollipopMmsConnection(Context context) {
-    super(context, ACTION);
-  }
-
-  @TargetApi(VERSION_CODES.LOLLIPOP_MR1)
-  @Override
-  public synchronized void onResult(Context context, Intent intent) {
-    if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP_MR1) {
-      Log.i(TAG, "HTTP status: " + intent.getIntExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, -1));
-    }
-
-    response = intent.getByteArrayExtra(SmsManager.EXTRA_MMS_DATA);
-  }
-
-  @Override
-  @TargetApi(VERSION_CODES.LOLLIPOP)
-  public @Nullable synchronized SendConf send(@NonNull byte[] pduBytes, int subscriptionId)
-      throws UndeliverableMessageException
-  {
-    beginTransaction();
-    try {
-      MmsBodyProvider.Pointer pointer = MmsBodyProvider.makeTemporaryPointer(getContext());
-      Util.copy(new ByteArrayInputStream(pduBytes), pointer.getOutputStream());
-
-      SmsManager smsManager;
-
-      if (VERSION.SDK_INT >= 22 && subscriptionId != -1) {
-        smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
-      } else {
-        smsManager = SmsManager.getDefault();
-      }
-
-      Bundle configOverrides = new Bundle();
-      configOverrides.putBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED, true);
-
-      MmsConfig mmsConfig = MmsConfigManager.getMmsConfig(getContext(), subscriptionId);
-
-      if (mmsConfig != null) {
-        MmsConfig.Overridden overridden = new MmsConfig.Overridden(mmsConfig, new Bundle());
-        configOverrides.putString(SmsManager.MMS_CONFIG_HTTP_PARAMS, overridden.getHttpParams());
-        configOverrides.putInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE, overridden.getMaxMessageSize());
-      }
-
-      smsManager.sendMultimediaMessage(getContext(),
-                                       pointer.getUri(),
-                                       null,
-                                       configOverrides,
-                                       getPendingIntent());
-
-      waitForResult();
-
-      Log.i(TAG, "MMS broadcast received and processed.");
-      pointer.close();
-
-      if (response == null) {
-        throw new UndeliverableMessageException("Null response.");
-      }
-
-      return (SendConf) new PduParser(response).parse();
-    } catch (IOException | TimeoutException e) {
-      throw new UndeliverableMessageException(e);
-    } finally {
-      endTransaction();
-    }
-  }
-}
-
diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java b/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java
deleted file mode 100644
index 6f4b0cea89..0000000000
--- a/app/src/main/java/org/thoughtcrime/securesms/mms/OutgoingMmsConnection.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package org.thoughtcrime.securesms.mms;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import com.google.android.mms.pdu_alt.SendConf;
-
-import org.thoughtcrime.securesms.transport.UndeliverableMessageException;
-
-
-public interface OutgoingMmsConnection {
-  @Nullable
-  SendConf send(@NonNull byte[] pduBytes, int subscriptionId) throws UndeliverableMessageException;
-}