Snap for 10447354 from 3f3579d43fb3fab598f81ee1eb773d64a90e5a02 to mainline-cellbroadcast-release

Change-Id: I955c90aae17b11eddb2c4b6bf8b9314fbd5af048
diff --git a/src/android/support/v7/mms/DefaultApnSettingsLoader.java b/src/android/support/v7/mms/DefaultApnSettingsLoader.java
index 2c2ba67..a4bd647 100644
--- a/src/android/support/v7/mms/DefaultApnSettingsLoader.java
+++ b/src/android/support/v7/mms/DefaultApnSettingsLoader.java
@@ -394,7 +394,7 @@
     private void loadFromResources(final int subId, final String apnName, final List<Apn> apns) {
         Log.i(MmsService.TAG, "Loading APNs from resources, apnName=" + apnName);
         final int[] mccMnc = Utils.getMccMnc(mContext, subId);
-        if (mccMnc[0] == 0 && mccMnc[0] == 0) {
+        if (mccMnc[0] == 0) {
             Log.w(MmsService.TAG, "Can not get valid mcc/mnc from system");
             return;
         }
diff --git a/src/android/support/v7/mms/MmsNetworkManager.java b/src/android/support/v7/mms/MmsNetworkManager.java
index 059ca8f..1021b5a 100644
--- a/src/android/support/v7/mms/MmsNetworkManager.java
+++ b/src/android/support/v7/mms/MmsNetworkManager.java
@@ -324,7 +324,8 @@
 
     private void registerConnectivityChangeReceiverLocked() {
         if (!mReceiverRegistered) {
-            mContext.registerReceiver(mConnectivityChangeReceiver, mConnectivityIntentFilter);
+            mContext.registerReceiver(mConnectivityChangeReceiver, mConnectivityIntentFilter,
+                    Context.RECEIVER_EXPORTED/*UNAUDITED*/);
             mReceiverRegistered = true;
         }
     }
diff --git a/src/android/support/v7/mms/pdu/EncodedStringValue.java b/src/android/support/v7/mms/pdu/EncodedStringValue.java
index 5ae1e43..0a5d2be 100644
--- a/src/android/support/v7/mms/pdu/EncodedStringValue.java
+++ b/src/android/support/v7/mms/pdu/EncodedStringValue.java
@@ -188,7 +188,6 @@
      */
     @Override
     public Object clone() throws CloneNotSupportedException {
-        super.clone();
         int len = mData.length;
         byte[] dstBytes = new byte[len];
         System.arraycopy(mData, 0, dstBytes, 0, len);
diff --git a/src/com/android/messaging/BugleApplication.java b/src/com/android/messaging/BugleApplication.java
index 0ef8d91..36f062b 100644
--- a/src/com/android/messaging/BugleApplication.java
+++ b/src/com/android/messaging/BugleApplication.java
@@ -132,7 +132,8 @@
                 LogUtil.i(TAG, "Carrier config changed. Reloading MMS config.");
                 MmsConfig.loadAsync();
             }
-        }, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        }, new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED),
+        Context.RECEIVER_EXPORTED/*UNAUDITED*/);
     }
 
     private static void initMmsLib(final Context context, final BugleGservices bugleGservices,
diff --git a/src/com/android/messaging/datamodel/DatabaseWrapper.java b/src/com/android/messaging/datamodel/DatabaseWrapper.java
index ca7a331..c08d5aa 100644
--- a/src/com/android/messaging/datamodel/DatabaseWrapper.java
+++ b/src/com/android/messaging/datamodel/DatabaseWrapper.java
@@ -190,7 +190,7 @@
         }
         if (mLog) {
             printTiming(t1, String.format(Locale.US,
-                    "insertWithOnConflict with ", searchTable));
+                    "insertWithOnConflict with %s", searchTable));
         }
     }
 
diff --git a/src/com/android/messaging/mmslib/pdu/EncodedStringValue.java b/src/com/android/messaging/mmslib/pdu/EncodedStringValue.java
index 1d3c9ea..5870027 100644
--- a/src/com/android/messaging/mmslib/pdu/EncodedStringValue.java
+++ b/src/com/android/messaging/mmslib/pdu/EncodedStringValue.java
@@ -203,7 +203,6 @@
      */
     @Override
     public Object clone() throws CloneNotSupportedException {
-        super.clone();
         int len = mData.length;
         byte[] dstBytes = new byte[len];
         System.arraycopy(mData, 0, dstBytes, 0, len);
diff --git a/src/com/android/messaging/ui/conversation/ConversationActivity.java b/src/com/android/messaging/ui/conversation/ConversationActivity.java
index be94460..d8d3157 100644
--- a/src/com/android/messaging/ui/conversation/ConversationActivity.java
+++ b/src/com/android/messaging/ui/conversation/ConversationActivity.java
@@ -360,6 +360,7 @@
         return mUiState.shouldResumeComposeMessage();
     }
 
+    @SuppressWarnings("MissingSuperCall") // TODO: fix me
     @Override
     protected void onActivityResult(final int requestCode, final int resultCode,
             final Intent data) {
diff --git a/src/com/android/messaging/ui/conversation/LaunchConversationActivity.java b/src/com/android/messaging/ui/conversation/LaunchConversationActivity.java
index 5500ae8..c869839 100644
--- a/src/com/android/messaging/ui/conversation/LaunchConversationActivity.java
+++ b/src/com/android/messaging/ui/conversation/LaunchConversationActivity.java
@@ -37,6 +37,8 @@
 
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Launches ConversationActivity for sending a message to, or viewing messages from, a specific
@@ -46,6 +48,7 @@
  */
 public class LaunchConversationActivity extends Activity implements
         LaunchConversationData.LaunchConversationDataListener {
+    private static final int MAX_RECIPIENT_LENGTH = 100;
     static final String SMS_BODY = "sms_body";
     static final String ADDRESS = "address";
     final Binding<LaunchConversationData> mBinding = BindingBase.createBinding(this);
@@ -76,6 +79,9 @@
                     recipients = new String[] { intent.getStringExtra(Intent.EXTRA_EMAIL) };
                 }
             }
+            if (recipients != null) {
+                recipients = trimInvalidRecipients(recipients);
+            }
             mSmsBody = intent.getStringExtra(SMS_BODY);
             if (TextUtils.isEmpty(mSmsBody)) {
                 // Used by intents sent from the web YouTube (and perhaps others).
@@ -103,6 +109,20 @@
         finish();
     }
 
+    private String[] trimInvalidRecipients(String[] recipients) {
+        List<String> trimmedRecipients = new ArrayList<>();
+        for (String recipient : recipients) {
+            if (recipient.length() < MAX_RECIPIENT_LENGTH) {
+                trimmedRecipients.add(recipient);
+            }
+        }
+        if (trimmedRecipients.size() > 0) {
+            return trimmedRecipients.toArray(new String[0]);
+        } else {
+            return null;
+        }
+    }
+
     private String getBody(final Uri uri) {
         if (uri == null) {
             return null;
diff --git a/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java b/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java
index f3de0ab..a2b0bdf 100644
--- a/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java
+++ b/src/com/android/messaging/ui/conversationlist/AbstractConversationListActivity.java
@@ -105,6 +105,7 @@
         return isInConversationListSelectMode();
     }
 
+    @SuppressWarnings("MissingSuperCall") // TODO: fix me
     @Override
     public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
     }
diff --git a/src/com/android/messaging/util/Dates.java b/src/com/android/messaging/util/Dates.java
index d012dfd..49f0c7f 100644
--- a/src/com/android/messaging/util/Dates.java
+++ b/src/com/android/messaging/util/Dates.java
@@ -18,13 +18,16 @@
 
 import android.content.Context;
 import android.text.format.DateUtils;
-import android.text.format.Time;
 
 import com.android.messaging.Factory;
 import com.android.messaging.R;
 import com.google.common.annotations.VisibleForTesting;
 
 import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.time.ZoneId;
 import java.util.Date;
 import java.util.Locale;
 
@@ -265,16 +268,11 @@
         return String.format(format, count);
     }
 
-    private static synchronized long getNumberOfDaysPassed(final long date1, final long date2) {
-        if (sThenTime == null) {
-            sThenTime = new Time();
-        }
-        sThenTime.set(date1);
-        final int day1 = Time.getJulianDay(date1, sThenTime.gmtoff);
-        sThenTime.set(date2);
-        final int day2 = Time.getJulianDay(date2, sThenTime.gmtoff);
-        return Math.abs(day2 - day1);
+    private static long getNumberOfDaysPassed(final long date1, final long date2) {
+        LocalDateTime dateTime1 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date1),
+                                                          ZoneId.systemDefault());
+        LocalDateTime dateTime2 = LocalDateTime.ofInstant(Instant.ofEpochMilli(date2),
+                                                          ZoneId.systemDefault());
+        return Math.abs(ChronoUnit.DAYS.between(dateTime2, dateTime1));
     }
-
-    private static Time sThenTime;
 }
diff --git a/src/com/android/messaging/util/FileUtil.java b/src/com/android/messaging/util/FileUtil.java
index 71fbb4b..e7d86f2 100644
--- a/src/com/android/messaging/util/FileUtil.java
+++ b/src/com/android/messaging/util/FileUtil.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.net.Uri;
 import android.os.Environment;
+import android.os.ParcelFileDescriptor;
 import android.text.TextUtils;
 
 import com.android.messaging.Factory;
@@ -28,6 +29,8 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Locale;
@@ -121,6 +124,10 @@
     // We're told it's possible to create world readable hardlinks to other apps private data
     // so we ban all /data file uris.
     public static boolean isInPrivateDir(Uri uri) {
+        return isFileUriInPrivateDir(uri) || isContentUriInPrivateDir(uri);
+    }
+
+    private static boolean isFileUriInPrivateDir(Uri uri) {
         if (!UriUtil.isFileUri(uri)) {
             return false;
         }
@@ -128,6 +135,24 @@
         return FileUtil.isSameOrSubDirectory(Environment.getDataDirectory(), file);
     }
 
+    private static boolean isContentUriInPrivateDir(Uri uri) {
+        if (!uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
+            return false;
+        }
+        try {
+            Context context = Factory.get().getApplicationContext();
+            ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
+            int fd = pfd.getFd();
+            // Use the file descriptor to find out the read file path through symbolic link.
+            Path fdPath = Paths.get("/proc/self/fd/" + fd);
+            Path filePath = java.nio.file.Files.readSymbolicLink(fdPath);
+            pfd.close();
+            return FileUtil.isSameOrSubDirectory(Environment.getDataDirectory(), filePath.toFile());
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
     /**
      * Checks, whether the child directory is the same as, or a sub-directory of the base
      * directory.
diff --git a/src/com/android/messaging/util/SwitchCompatUtils.java b/src/com/android/messaging/util/SwitchCompatUtils.java
index 8cfe2bc..9c920f6 100644
--- a/src/com/android/messaging/util/SwitchCompatUtils.java
+++ b/src/com/android/messaging/util/SwitchCompatUtils.java
@@ -21,7 +21,7 @@
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import androidx.appcompat.graphics.drawable.DrawableWrapper;
+import androidx.appcompat.graphics.drawable.DrawableWrapperCompat;
 import androidx.appcompat.widget.SwitchCompat;
 import android.util.TypedValue;
 
@@ -53,8 +53,8 @@
     private static Drawable getColorTintedDrawable(Drawable oldDrawable,
             final ColorStateList colorStateList, final PorterDuff.Mode mode) {
         final int[] thumbState = oldDrawable.isStateful() ? oldDrawable.getState() : null;
-        if (oldDrawable instanceof DrawableWrapper) {
-            oldDrawable = ((DrawableWrapper) oldDrawable).getWrappedDrawable();
+        if (oldDrawable instanceof DrawableWrapperCompat) {
+            oldDrawable = ((DrawableWrapperCompat) oldDrawable).getDrawable();
         }
         final Drawable newDrawable = new TintDrawableWrapper(oldDrawable, colorStateList, mode);
         if (thumbState != null) {
diff --git a/src/com/android/messaging/util/TintDrawableWrapper.java b/src/com/android/messaging/util/TintDrawableWrapper.java
index 06ee7d4..b426f8c 100644
--- a/src/com/android/messaging/util/TintDrawableWrapper.java
+++ b/src/com/android/messaging/util/TintDrawableWrapper.java
@@ -20,16 +20,16 @@
 import android.graphics.Color;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
-import androidx.appcompat.graphics.drawable.DrawableWrapper;
+import androidx.appcompat.graphics.drawable.DrawableWrapperCompat;
 
 /*
  * This is directly copied from v7/appcompat/src/androidx.appcompat.internal/widget/TintManager.java
  */
 
 /**
- * A {@link DrawableWrapper} which updates it's color filter using a {@link ColorStateList}.
+ * A {@link DrawableWrapperCompat} which updates it's color filter using a {@link ColorStateList}.
  */
-class TintDrawableWrapper extends DrawableWrapper {
+class TintDrawableWrapper extends DrawableWrapperCompat {
     private final ColorStateList mTintStateList;
     private final PorterDuff.Mode mTintMode;
     private int mCurrentColor;
diff --git a/tests/src/com/android/messaging/ui/mediapicker/CameraManagerTest.java b/tests/src/com/android/messaging/ui/mediapicker/CameraManagerTest.java
index 951c694..e81a548 100644
--- a/tests/src/com/android/messaging/ui/mediapicker/CameraManagerTest.java
+++ b/tests/src/com/android/messaging/ui/mediapicker/CameraManagerTest.java
@@ -44,10 +44,14 @@
         CameraManager.setCameraWrapper(MockCameraFactory.createCameraWrapper());
         assertEquals(false, CameraManager.get().hasAnyCamera());
         assertEquals(false, CameraManager.get().hasFrontAndBackCamera());
+        boolean threw = false;
         try {
             CameraManager.get().selectCamera(CameraInfo.CAMERA_FACING_BACK);
-            fail("selectCamera should have thrown");
         } catch (AssertionError e) {
+            threw = true;
+        }
+        if (!threw) {
+            fail("selectCamera should have thrown");
         }
     }
 
diff --git a/tests/src/com/android/messaging/util/ContactUtilTest.java b/tests/src/com/android/messaging/util/ContactUtilTest.java
index 48a7ced..4f0ca9b 100644
--- a/tests/src/com/android/messaging/util/ContactUtilTest.java
+++ b/tests/src/com/android/messaging/util/ContactUtilTest.java
@@ -131,7 +131,7 @@
                 } while (cur.moveToNext());
             }
         } catch (final Exception e) {
-            System.out.println(e.getStackTrace());
+            LogUtil.e(LogUtil.BUGLE_TAG, "Failed to delete test contacts", e);
         }
     }