diff --git a/Android.bp b/Android.bp
index e7e78ae..b586dc6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -19,6 +19,21 @@
     default_applicable_licenses: ["Android-Apache-2.0"],
 }
 
+genrule {
+    name: "statslog-mms-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module mms"
+        + " --javaPackage com.android.mms --javaClass MmsStatsLog",
+    out: ["com/android/mms/MmsStatsLog.java"],
+}
+
+java_library {
+    name: "mms-statsd",
+    srcs: [
+        ":statslog-mms-java-gen",
+    ],
+}
+
 android_app {
     name: "MmsService",
     platform_apis: true,
@@ -30,4 +45,16 @@
         proguard_flags_files: ["proguard.flags"],
     },
     certificate: "platform",
+    static_libs: [
+        "mms-protos-lite",
+        "mms-statsd",
+        "androidx.annotation_annotation",
+    ],
+}
+
+filegroup {
+    name: "mms-service-srcs",
+    srcs: [
+        "src/com/android/mms/service/**/*.java",
+    ],
 }
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 87e7947..a19a11a 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -26,6 +26,10 @@
     <uses-permission android:name="android.permission.BROADCAST_WAP_PUSH"/>
     <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES"/>
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS"/>
+    <!-- Needed to check if subscription is active. -->
+    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
+    <!-- Needed to query user associated with a subscription. -->
+    <uses-permission android:name="android.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION"/>
 
     <protected-broadcast android:name="android.settings.ENABLE_MMS_DATA_REQUEST"/>
 
diff --git a/proto/Android.bp b/proto/Android.bp
new file mode 100644
index 0000000..b55e987
--- /dev/null
+++ b/proto/Android.bp
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+ package {
+     default_applicable_licenses: ["Android-Apache-2.0"],
+ }
+
+ java_library_static {
+     name: "mms-protos-lite",
+     proto: {
+         type: "lite",
+     },
+     sdk_version: "system_current",
+     min_sdk_version: "33",
+     srcs: ["src/persist_mms_atoms.proto"],
+ }
\ No newline at end of file
diff --git a/proto/src/persist_mms_atoms.proto b/proto/src/persist_mms_atoms.proto
new file mode 100644
index 0000000..bde1cb9
--- /dev/null
+++ b/proto/src/persist_mms_atoms.proto
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package com.android.mms;
+option java_package = "com.android.mms";
+option java_outer_classname = "PersistMmsAtomsProto";
+option java_multiple_files = true;
+
+message PersistMmsAtoms {
+  /* Last Android build fingerprint. This usually changes after system OTA. */
+  optional string build_fingerprint = 1;
+
+  /* Incoming MMS statistics and information. */
+  repeated IncomingMms incoming_mms = 2;
+
+  /* Timestamp of last incoming_mms pull. */
+  optional int64 incoming_mms_pull_timestamp_millis = 3;
+
+  /* Outgoing MMS statistics and information. */
+  repeated OutgoingMms outgoing_mms = 4;
+
+  /* Timestamp of last outgoing_mms pull. */
+  optional int64 outgoing_mms_pull_timestamp_millis = 5;
+}
+
+message IncomingMms {
+  optional int32 rat = 1;
+  optional int32 result = 2;
+  optional int32 roaming = 3;
+  optional int32 sim_slot_index = 4;
+  optional bool is_multi_sim = 5;
+  optional bool is_esim = 6;
+  optional int32 carrier_id = 7;
+  optional int64 avg_interval_millis = 8;
+  optional int64 mms_count = 9;
+  optional int32 retry_id = 10;
+  optional bool handled_by_carrier_app = 11;
+  optional bool is_managed_profile = 12;
+}
+
+message OutgoingMms {
+  optional int32 rat = 1;
+  optional int32 result = 2;
+  optional int32 roaming = 3;
+  optional int32 sim_slot_index = 4;
+  optional bool is_multi_sim = 5;
+  optional bool is_esim = 6;
+  optional int32 carrier_id = 7;
+  optional int64 avg_interval_millis = 8;
+  optional int64 mms_count = 9;
+  optional bool is_from_default_app = 10;
+  optional int32 retry_id = 11;
+  optional bool handled_by_carrier_app = 12;
+  optional bool is_managed_profile = 13;
+}
diff --git a/src/com/android/mms/service/DownloadRequest.java b/src/com/android/mms/service/DownloadRequest.java
index 0f12415..62fa9e6 100644
--- a/src/com/android/mms/service/DownloadRequest.java
+++ b/src/com/android/mms/service/DownloadRequest.java
@@ -38,6 +38,8 @@
 import android.text.TextUtils;
 
 import com.android.mms.service.exception.MmsHttpException;
+import com.android.mms.service.metrics.MmsStats;
+
 import com.google.android.mms.MmsException;
 import com.google.android.mms.pdu.GenericPdu;
 import com.google.android.mms.pdu.PduHeaders;
@@ -59,8 +61,8 @@
 
     public DownloadRequest(RequestManager manager, int subId, String locationUrl,
             Uri contentUri, PendingIntent downloadedIntent, String creator,
-            Bundle configOverrides, Context context, long messageId) {
-        super(manager, subId, creator, configOverrides, context, messageId);
+            Bundle configOverrides, Context context, long messageId, MmsStats mmsStats) {
+        super(manager, subId, creator, configOverrides, context, messageId, mmsStats);
         mLocationUrl = locationUrl;
         mDownloadedIntent = downloadedIntent;
         mContentUri = contentUri;
@@ -296,10 +298,12 @@
             if (mCarrierMessagingServiceWrapper.bindToCarrierMessagingService(
                     context, carrierMessagingServicePackage, Runnable::run,
                     ()->onServiceReady())) {
-                LogUtil.v("bindService() for carrier messaging service succeeded. "
+                LogUtil.v("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " succeeded. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
             } else {
-                LogUtil.e("bindService() for carrier messaging service failed. "
+                LogUtil.e("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " failed. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
                 carrierDownloadCallback.onDownloadMmsComplete(
                         CarrierMessagingService.DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK);
diff --git a/src/com/android/mms/service/MmsConstants.java b/src/com/android/mms/service/MmsConstants.java
new file mode 100644
index 0000000..57ef5df
--- /dev/null
+++ b/src/com/android/mms/service/MmsConstants.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service;
+
+import java.util.UUID;
+
+public class MmsConstants {
+    // MMS anomaly uuid
+    public static final UUID MMS_ANOMALY_UUID = UUID.fromString(
+            "e4330975-17be-43b7-87d6-d9f281d33278");
+}
diff --git a/src/com/android/mms/service/MmsHttpClient.java b/src/com/android/mms/service/MmsHttpClient.java
index 5cec66f..b54b1aa 100644
--- a/src/com/android/mms/service/MmsHttpClient.java
+++ b/src/com/android/mms/service/MmsHttpClient.java
@@ -52,6 +52,8 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * MMS HTTP client for sending and downloading MMS messages
  */
@@ -452,6 +454,21 @@
         return sb.toString();
     }
 
+    private static String getPhoneNumberForMacroLine1(TelephonyManager telephonyManager,
+        Context context, int subId) {
+        String phoneNo = telephonyManager.getLine1Number();
+        if (TextUtils.isEmpty(phoneNo)) {
+            SubscriptionManager subscriptionManager = context.getSystemService(
+                SubscriptionManager.class);
+            if (subscriptionManager != null) {
+                phoneNo = subscriptionManager.getPhoneNumber(subId);
+            } else {
+                LogUtil.e("subscriptionManager is null");
+            }
+        }
+        return phoneNo;
+    }
+
     /*
      * Macro names
      */
@@ -471,15 +488,16 @@
      * @param subId     The subscription ID used to get line number, etc.
      * @return The value of the defined macro
      */
-    private static String getMacroValue(Context context, String macro, Bundle mmsConfig,
-            int subId) {
+    @VisibleForTesting
+    public static String getMacroValue(Context context, String macro, Bundle mmsConfig,
+        int subId) {
         final TelephonyManager telephonyManager = ((TelephonyManager) context.getSystemService(
             Context.TELEPHONY_SERVICE)).createForSubscriptionId(subId);
         if (MACRO_LINE1.equals(macro)) {
-            return telephonyManager.getLine1Number();
+            return getPhoneNumberForMacroLine1(telephonyManager, context, subId);
         } else if (MACRO_LINE1NOCOUNTRYCODE.equals(macro)) {
             return PhoneUtils.getNationalNumber(telephonyManager,
-                telephonyManager.getLine1Number());
+                getPhoneNumberForMacroLine1(telephonyManager, context, subId));
         } else if (MACRO_NAI.equals(macro)) {
             return getNai(telephonyManager, mmsConfig);
         }
diff --git a/src/com/android/mms/service/MmsNetworkManager.java b/src/com/android/mms/service/MmsNetworkManager.java
index 6799d29..f21e510 100644
--- a/src/com/android/mms/service/MmsNetworkManager.java
+++ b/src/com/android/mms/service/MmsNetworkManager.java
@@ -26,11 +26,16 @@
 import android.net.NetworkInfo;
 import android.net.NetworkRequest;
 import android.net.TelephonyNetworkSpecifier;
+import android.os.Binder;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
 import android.provider.DeviceConfig;
+import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConstants;
@@ -52,9 +57,8 @@
     // timeout to make sure we don't bail prematurely.
     private static final int ADDITIONAL_NETWORK_ACQUIRE_TIMEOUT_MILLIS = (5 * 1000);
 
-    // Waiting time used before releasing a network prematurely. This allows the MMS download
-    // acknowledgement messages to be sent using the same network that was used to download the data
-    private static final int NETWORK_RELEASE_TIMEOUT_MILLIS = 5 * 1000;
+    /* Event created when receiving ACTION_CARRIER_CONFIG_CHANGED */
+    private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;
 
     private final Context mContext;
 
@@ -88,17 +92,43 @@
     private int mPhoneId;
 
     // If ACTION_SIM_CARD_STATE_CHANGED intent receiver is registered
-    private boolean mReceiverRegistered;
+    private boolean mSimCardStateChangedReceiverRegistered;
 
     private final Dependencies mDeps;
 
+    private int mNetworkReleaseTimeoutMillis;
+    private EventHandler mEventHandler;
+
+    private final class EventHandler extends Handler {
+        EventHandler() {
+            super(Looper.getMainLooper());
+        }
+
+        /**
+         * Handles events coming from the phone stack. Overridden from handler.
+         *
+         * @param msg the message to handle
+         */
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case EVENT_CARRIER_CONFIG_CHANGED:
+                    // Reload mNetworkReleaseTimeoutMillis from CarrierConfigManager.
+                    handleCarrierConfigChanged();
+                    break;
+                default:
+                    LogUtil.e("MmsNetworkManager: ignoring message of unexpected type " + msg.what);
+            }
+        }
+    }
+
     /**
      * This receiver listens to ACTION_SIM_CARD_STATE_CHANGED after starting a new NetworkRequest.
      * If ACTION_SIM_CARD_STATE_CHANGED with SIM_STATE_ABSENT for a SIM card corresponding to the
      * current NetworkRequest is received, it just releases the NetworkRequest without waiting for
      * timeout.
      */
-    private final BroadcastReceiver mReceiver =
+    private final BroadcastReceiver mSimCardStateChangedReceiver =
             new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
@@ -140,6 +170,35 @@
     }
 
     /**
+     * This receiver listens to ACTION_CARRIER_CONFIG_CHANGED. Whenever receiving this event,
+     * mNetworkReleaseTimeoutMillis needs to be reloaded from CarrierConfigManager.
+     */
+    private final BroadcastReceiver mCarrierConfigChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
+                    && mSubId == intent.getIntExtra(
+                            CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                            SubscriptionManager.DEFAULT_SUBSCRIPTION_ID)) {
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                        EVENT_CARRIER_CONFIG_CHANGED));
+            }
+        }
+    };
+
+    private void handleCarrierConfigChanged() {
+        final CarrierConfigManager configManager =
+                (CarrierConfigManager)
+                        mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        final PersistableBundle config = configManager.getConfigForSubId(mSubId);
+        mNetworkReleaseTimeoutMillis =
+                config.getInt(CarrierConfigManager.KEY_MMS_NETWORK_RELEASE_TIMEOUT_MILLIS_INT);
+        LogUtil.d("MmsNetworkManager: handleCarrierConfigChanged() mNetworkReleaseTimeoutMillis "
+                + mNetworkReleaseTimeoutMillis);
+    }
+
+    /**
      * Network callback for our network request
      */
     private class NetworkRequestCallback extends ConnectivityManager.NetworkCallback {
@@ -245,6 +304,13 @@
                 }
             }
         };
+
+        mEventHandler = new EventHandler();
+        // Register a receiver to listen to ACTION_CARRIER_CONFIG_CHANGED
+        mContext.registerReceiver(
+                mCarrierConfigChangedReceiver,
+                new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
+        handleCarrierConfigChanged();
     }
 
     public MmsNetworkManager(Context context, int subId) {
@@ -270,7 +336,7 @@
                 return;
             }
 
-            if (!mReceiverRegistered) {
+            if (!mSimCardStateChangedReceiverRegistered) {
                 mPhoneId = mDeps.getPhoneId(mSubId);
                 if (mPhoneId == SubscriptionManager.INVALID_PHONE_INDEX
                         || mPhoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) {
@@ -279,9 +345,9 @@
 
                 // Register a receiver to listen to ACTION_SIM_CARD_STATE_CHANGED
                 mContext.registerReceiver(
-                        mReceiver,
+                        mSimCardStateChangedReceiver,
                         new IntentFilter(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED));
-                mReceiverRegistered = true;
+                mSimCardStateChangedReceiverRegistered = true;
             }
 
             // Not available, so start a new request if not done yet
@@ -297,10 +363,10 @@
                 LogUtil.w(requestId, "MmsNetworkManager: acquire network wait interrupted");
             }
 
-            if (mReceiverRegistered) {
+            if (mSimCardStateChangedReceiverRegistered) {
                 // Unregister the receiver.
-                mContext.unregisterReceiver(mReceiver);
-                mReceiverRegistered = false;
+                mContext.unregisterReceiver(mSimCardStateChangedReceiver);
+                mSimCardStateChangedReceiverRegistered = false;
             }
 
             if (mNetwork != null) {
@@ -328,10 +394,11 @@
     /**
      * Release the MMS network when nobody is holding on to it.
      *
-     * @param requestId          request ID for logging
-     * @param shouldDelayRelease whether the release should be delayed for 5 seconds, the regular
-     *                           use case is to delay this for DownloadRequests to use the network
-     *                           for sending an acknowledgement on the same network
+     * @param requestId          request ID for logging.
+     * @param shouldDelayRelease whether the release should be delayed for a carrier-configured
+     *                           timeout (default 5 seconds), the regular use case is to delay this
+     *                           for DownloadRequests to use the network for sending an
+     *                           acknowledgement on the same network.
      */
     public void releaseNetwork(final String requestId, final boolean shouldDelayRelease) {
         synchronized (this) {
@@ -344,7 +411,7 @@
                         // handler to release the network
                         mReleaseHandler.removeCallbacks(mNetworkReleaseTask);
                         mReleaseHandler.postDelayed(mNetworkReleaseTask,
-                                NETWORK_RELEASE_TIMEOUT_MILLIS);
+                                mNetworkReleaseTimeoutMillis);
                     } else {
                         releaseRequestLocked(mNetworkCallback);
                     }
@@ -443,4 +510,9 @@
         }
         return apnName;
     }
+
+    @VisibleForTesting
+    protected int getNetworkReleaseTimeoutMillis() {
+        return mNetworkReleaseTimeoutMillis;
+    }
 }
diff --git a/src/com/android/mms/service/MmsRequest.java b/src/com/android/mms/service/MmsRequest.java
index dfef1cc..dca77df 100644
--- a/src/com/android/mms/service/MmsRequest.java
+++ b/src/com/android/mms/service/MmsRequest.java
@@ -39,6 +39,7 @@
 import com.android.mms.service.exception.ApnException;
 import com.android.mms.service.exception.MmsHttpException;
 import com.android.mms.service.exception.MmsNetworkException;
+import com.android.mms.service.metrics.MmsStats;
 
 import java.util.UUID;
 
@@ -49,8 +50,6 @@
     private static final int RETRY_TIMES = 3;
     // Signal level threshold for both wifi and cellular
     private static final int SIGNAL_LEVEL_THRESHOLD = 2;
-    // MMS anomaly uuid
-    private final UUID mAnomalyUUID = UUID.fromString("e4330975-17be-43b7-87d6-d9f281d33278");
     public static final String EXTRA_LAST_CONNECTION_FAILURE_CAUSE_CODE
             = "android.telephony.extra.LAST_CONNECTION_FAILURE_CAUSE_CODE";
     public static final String EXTRA_HANDLED_BY_CARRIER_APP
@@ -101,6 +100,7 @@
     protected Context mContext;
     protected long mMessageId;
     protected int mLastConnectionFailure;
+    private MmsStats mMmsStats;
 
     class MonitorTelephonyCallback extends TelephonyCallback implements
             TelephonyCallback.PreciseDataConnectionStateListener {
@@ -121,13 +121,14 @@
     }
 
     public MmsRequest(RequestManager requestManager, int subId, String creator,
-            Bundle mmsConfig, Context context, long messageId) {
+            Bundle mmsConfig, Context context, long messageId, MmsStats mmsStats) {
         mRequestManager = requestManager;
         mSubId = subId;
         mCreator = creator;
         mMmsConfig = mmsConfig;
         mContext = context;
         mMessageId = messageId;
+        mMmsStats = mmsStats;
     }
 
     public int getSubId() {
@@ -146,6 +147,7 @@
         int result = SmsManager.MMS_ERROR_UNSPECIFIED;
         int httpStatusCode = 0;
         byte[] response = null;
+        int retryId = 0;
         // TODO: add mms data channel check back to fast fail if no way to send mms,
         // when telephony provides such API.
         if (!prepareForHttpRequest()) { // Prepare request, like reading pdu data from user
@@ -154,7 +156,7 @@
         } else { // Execute
             long retryDelaySecs = 2;
             // Try multiple times of MMS HTTP request, depending on the error.
-            for (int i = 0; i < RETRY_TIMES; i++) {
+            for (retryId = 0; retryId < RETRY_TIMES; retryId++) {
                 httpStatusCode = 0; // Clear for retry.
                 MonitorTelephonyCallback connectionStateCallback = new MonitorTelephonyCallback();
                 try {
@@ -212,7 +214,8 @@
                 retryDelaySecs <<= 1;
             }
         }
-        processResult(context, result, response, httpStatusCode, /* handledByCarrierApp= */ false);
+        processResult(context, result, response, httpStatusCode, /* handledByCarrierApp= */ false,
+                retryId);
     }
 
     private void listenToDataConnectionState(MonitorTelephonyCallback connectionStateCallback) {
@@ -240,6 +243,11 @@
      */
     public void processResult(Context context, int result, byte[] response, int httpStatusCode,
             boolean handledByCarrierApp) {
+        processResult(context, result, response, httpStatusCode, handledByCarrierApp, 0);
+    }
+
+    private void processResult(Context context, int result, byte[] response, int httpStatusCode,
+            boolean handledByCarrierApp, int retryId) {
         final Uri messageUri = persistIfRequired(context, result, response);
 
         final String requestId = this.getRequestId();
@@ -276,6 +284,7 @@
                 }
                 reportPossibleAnomaly(result, httpStatusCode);
                 pendingIntent.send(context, result, fillIn);
+                mMmsStats.addAtomToStorage(result, retryId, handledByCarrierApp);
             } catch (PendingIntent.CanceledException e) {
                 LogUtil.e(requestId, "Sending pending intent canceled", e);
             }
@@ -314,8 +323,9 @@
     private UUID generateUUID(int result, int httpStatusCode) {
         long lresult = result;
         long lhttpStatusCode = httpStatusCode;
-        return new UUID(mAnomalyUUID.getMostSignificantBits(),
-                mAnomalyUUID.getLeastSignificantBits() + ((lhttpStatusCode << 32) + lresult));
+        return new UUID(MmsConstants.MMS_ANOMALY_UUID.getMostSignificantBits(),
+                MmsConstants.MMS_ANOMALY_UUID.getLeastSignificantBits()
+                        + ((lhttpStatusCode << 32) + lresult));
     }
 
     private boolean isPoorSignal() {
diff --git a/src/com/android/mms/service/MmsService.java b/src/com/android/mms/service/MmsService.java
index d227b3c..ee88f09 100644
--- a/src/com/android/mms/service/MmsService.java
+++ b/src/com/android/mms/service/MmsService.java
@@ -41,6 +41,7 @@
 import android.provider.Telephony;
 import android.security.NetworkSecurityPolicy;
 import android.service.carrier.CarrierMessagingService;
+import android.telephony.AnomalyReporter;
 import android.telephony.SmsManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -51,6 +52,8 @@
 import android.util.SparseArray;
 
 import com.android.internal.telephony.IMms;
+import com.android.mms.service.metrics.MmsMetricsCollector;
+import com.android.mms.service.metrics.MmsStats;
 
 import com.google.android.mms.MmsException;
 import com.google.android.mms.pdu.DeliveryInd;
@@ -138,6 +141,8 @@
     // 1: download queue
     private final ExecutorService[] mRunningRequestExecutors = new ExecutorService[2];
 
+    private static MmsMetricsCollector mMmsMetricsCollector;
+
     private MmsNetworkManager getNetworkManager(int subId) {
         synchronized (mNetworkManagerCache) {
             MmsNetworkManager manager = mNetworkManagerCache.get(subId);
@@ -179,6 +184,8 @@
         List<String> carrierPackages = telephonyManager.getCarrierPackageNamesForIntent(intent);
 
         if (carrierPackages == null || carrierPackages.size() != 1) {
+            LogUtil.d("getCarrierMessagingServicePackageIfExists - multiple ("
+                    + carrierPackages.size() + ") carrier apps installed, not using any.");
             return null;
         } else {
             return carrierPackages.get(0);
@@ -211,19 +218,24 @@
             LogUtil.d("sendMessage " + formatCrossStackMessageId(messageId));
             enforceSystemUid();
 
+            MmsStats mmsStats = new MmsStats(MmsService.this,
+                    mMmsMetricsCollector.getAtomsStorage(), subId, getTelephonyManager(subId),
+                    callingPkg, false);
+
             // Make sure the subId is correct
             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                 LogUtil.e("Invalid subId " + subId);
-                sendErrorInPendingIntent(sentIntent, SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID);
+                handleError(sentIntent, SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID, mmsStats);
                 return;
             }
             if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                 subId = SubscriptionManager.getDefaultSmsSubscriptionId();
+                mmsStats.updateSubId(subId, getTelephonyManager(subId));
             }
 
             // Make sure the subId is active
             if (!isActiveSubId(subId)) {
-                sendErrorInPendingIntent(sentIntent, SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION);
+                handleError(sentIntent, SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION, mmsStats);
                 return;
             }
 
@@ -231,7 +243,7 @@
             Bundle mmsConfig = loadMmsConfig(subId);
             if (mmsConfig == null) {
                 LogUtil.e("MMS config is not loaded yet for subId " + subId);
-                sendErrorInPendingIntent(sentIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR);
+                handleError(sentIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR, mmsStats);
                 return;
             }
 
@@ -243,19 +255,21 @@
             // Make sure MMS is enabled
             if (!mmsConfig.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED)) {
                 LogUtil.e("MMS is not enabled for subId " + subId);
-                sendErrorInPendingIntent(sentIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR);
+                handleError(sentIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR, mmsStats);
                 return;
             }
 
             final SendRequest request = new SendRequest(MmsService.this, subId, contentUri,
-                    locationUrl, sentIntent, callingPkg, mmsConfig, MmsService.this, messageId);
+                    locationUrl, sentIntent, callingPkg, mmsConfig, MmsService.this,
+                    messageId, mmsStats);
 
             final String carrierMessagingServicePackage =
                     getCarrierMessagingServicePackageIfExists(subId);
 
             if (carrierMessagingServicePackage != null) {
-                LogUtil.d(request.toString(), "sending message by carrier app "
-                        + formatCrossStackMessageId(messageId));
+                LogUtil.d(request.toString(), "sending message by carrier app: "
+                        + carrierMessagingServicePackage
+                        + " " + formatCrossStackMessageId(messageId));
                 request.trySendingByCarrierApp(MmsService.this, carrierMessagingServicePackage);
                 return;
             }
@@ -269,7 +283,7 @@
                 // AcknowledgeInd and NotifyRespInd are parts of downloading sequence.
                 // TODO: Should consider ReadRecInd(Read Report)?
                 sendSettingsIntentForFailedMms(!isRawPduSendReq(contentUri), subId);
-                sendErrorInPendingIntent(sentIntent, SmsManager.MMS_ERROR_NO_DATA_NETWORK);
+                handleError(sentIntent, SmsManager.MMS_ERROR_NO_DATA_NETWORK, mmsStats);
                 return;
             }
 
@@ -288,22 +302,27 @@
 
             enforceSystemUid();
 
+            MmsStats mmsStats = new MmsStats(MmsService.this,
+                    mMmsMetricsCollector.getAtomsStorage(), subId, getTelephonyManager(subId),
+                    callingPkg, true);
+
             // Make sure the subId is correct
             if (!SubscriptionManager.isValidSubscriptionId(subId)) {
                 LogUtil.e("Invalid subId " + subId);
-                sendErrorInPendingIntent(downloadedIntent,
-                        SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID);
+                handleError(downloadedIntent, SmsManager.MMS_ERROR_INVALID_SUBSCRIPTION_ID,
+                        mmsStats);
                 return;
             }
             if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                 subId = SubscriptionManager.getDefaultSmsSubscriptionId();
+                mmsStats.updateSubId(subId, getTelephonyManager(subId));
             }
 
             if (!isActiveSubId(subId)) {
                 List<SubscriptionInfo> activeSubList = getActiveSubscriptionsInGroup(subId);
                 if (activeSubList.isEmpty()) {
-                    sendErrorInPendingIntent(downloadedIntent,
-                            SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION);
+                    handleError(downloadedIntent, SmsManager.MMS_ERROR_INACTIVE_SUBSCRIPTION,
+                            mmsStats);
                     return;
                 }
 
@@ -317,13 +336,13 @@
                     }
                 }
             }
+            mmsStats.updateSubId(subId, getTelephonyManager(subId));
 
             // Load MMS config
             Bundle mmsConfig = loadMmsConfig(subId);
             if (mmsConfig == null) {
                 LogUtil.e("MMS config is not loaded yet for subId " + subId);
-                sendErrorInPendingIntent(
-                        downloadedIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR);
+                handleError(downloadedIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR, mmsStats);
                 return;
             }
 
@@ -335,21 +354,21 @@
             // Make sure MMS is enabled
             if (!mmsConfig.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED)) {
                 LogUtil.e("MMS is not enabled for subId " + subId);
-                sendErrorInPendingIntent(
-                        downloadedIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR);
+                handleError(downloadedIntent, SmsManager.MMS_ERROR_CONFIGURATION_ERROR, mmsStats);
                 return;
             }
 
             final DownloadRequest request = new DownloadRequest(MmsService.this, subId, locationUrl,
                     contentUri, downloadedIntent, callingPkg, mmsConfig, MmsService.this,
-                    messageId);
+                    messageId, mmsStats);
 
             final String carrierMessagingServicePackage =
                     getCarrierMessagingServicePackageIfExists(subId);
 
             if (carrierMessagingServicePackage != null) {
-                LogUtil.d(request.toString(), "downloading message by carrier app "
-                        + formatCrossStackMessageId(messageId));
+                LogUtil.d(request.toString(), "downloading message by carrier app: "
+                        + carrierMessagingServicePackage
+                        + " " + formatCrossStackMessageId(messageId));
                 request.tryDownloadingByCarrierApp(MmsService.this, carrierMessagingServicePackage);
                 return;
             }
@@ -357,7 +376,7 @@
             // Make sure subId has MMS data
             if (!getTelephonyManager(subId).isDataEnabledForApn(ApnSetting.TYPE_MMS)) {
                 sendSettingsIntentForFailedMms(/*isIncoming=*/ true, subId);
-                sendErrorInPendingIntent(downloadedIntent, SmsManager.MMS_ERROR_DATA_DISABLED);
+                handleError(downloadedIntent, SmsManager.MMS_ERROR_DATA_DISABLED, mmsStats);
                 return;
             }
 
@@ -577,6 +596,14 @@
             }
             return false;
         }
+
+        private void handleError(@Nullable PendingIntent pendingIntent, int resultCode,
+                MmsStats mmsStats) {
+            sendErrorInPendingIntent(pendingIntent, resultCode);
+            mmsStats.addAtomToStorage(resultCode);
+            String message = "MMS failed" + " with error " + resultCode;
+            AnomalyReporter.reportAnomaly(MmsConstants.MMS_ANOMALY_UUID, message);
+        }
     };
 
     @Override
@@ -703,6 +730,9 @@
 
         NetworkSecurityPolicy.getInstance().setCleartextTrafficPermitted(true);
 
+        // Registers statsd pullers
+        mMmsMetricsCollector = new MmsMetricsCollector(this);
+
         // Initialize running request state
         for (int i = 0; i < mRunningRequestExecutors.length; i++) {
             mRunningRequestExecutors[i] = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
diff --git a/src/com/android/mms/service/SendRequest.java b/src/com/android/mms/service/SendRequest.java
index 67c368d..4f97d84 100644
--- a/src/com/android/mms/service/SendRequest.java
+++ b/src/com/android/mms/service/SendRequest.java
@@ -25,17 +25,21 @@
 import android.os.AsyncTask;
 import android.os.Binder;
 import android.os.Bundle;
+import android.os.UserHandle;
 import android.provider.BlockedNumberContract;
 import android.provider.Telephony;
 import android.service.carrier.CarrierMessagingService;
 import android.service.carrier.CarrierMessagingServiceWrapper;
 import android.telephony.SmsManager;
+import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.SmsApplication;
 import com.android.internal.telephony.SmsNumberUtils;
 import com.android.mms.service.exception.MmsHttpException;
+import com.android.mms.service.metrics.MmsStats;
+
 import com.google.android.mms.MmsException;
 import com.google.android.mms.pdu.EncodedStringValue;
 import com.google.android.mms.pdu.GenericPdu;
@@ -58,8 +62,8 @@
 
     public SendRequest(RequestManager manager, int subId, Uri contentUri, String locationUrl,
             PendingIntent sentIntent, String creator, Bundle configOverrides, Context context,
-            long messageId) {
-        super(manager, subId, creator, configOverrides, context, messageId);
+            long messageId, MmsStats mmsStats) {
+        super(manager, subId, creator, configOverrides, context, messageId, mmsStats);
         mPduUri = contentUri;
         mPduData = null;
         mLocationUrl = locationUrl;
@@ -172,10 +176,22 @@
     @Override
     protected Uri persistIfRequired(Context context, int result, byte[] response) {
         final String requestId = getRequestId();
-        if (!SmsApplication.shouldWriteMessageForPackage(mCreator, context)) {
-            // Not required to persist
+
+        SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
+        UserHandle userHandle = null;
+        long identity = Binder.clearCallingIdentity();
+        try {
+            if ((subManager != null) && (subManager.isActiveSubscriptionId(mSubId))) {
+                userHandle = subManager.getSubscriptionUserHandle(mSubId);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+
+        if (!SmsApplication.shouldWriteMessageForPackageAsUser(mCreator, context, userHandle)) {
             return null;
         }
+
         LogUtil.d(requestId, "persistIfRequired. "
                 + MmsService.formatCrossStackMessageId(mMessageId));
         if (mPduData == null) {
@@ -183,7 +199,7 @@
                     + MmsService.formatCrossStackMessageId(mMessageId));
             return null;
         }
-        final long identity = Binder.clearCallingIdentity();
+        identity = Binder.clearCallingIdentity();
         try {
             final boolean supportContentDisposition =
                     mMmsConfig.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION);
@@ -417,10 +433,12 @@
             if (mCarrierMessagingServiceWrapper.bindToCarrierMessagingService(
                     context, carrierMessagingServicePackage, Runnable::run,
                     () -> onServiceReady())) {
-                LogUtil.v("bindService() for carrier messaging service succeeded. "
+                LogUtil.v("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " succeeded. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
             } else {
-                LogUtil.e("bindService() for carrier messaging service failed. "
+                LogUtil.e("bindService() for carrier messaging service: "
+                        + carrierMessagingServicePackage + " failed. "
                         + MmsService.formatCrossStackMessageId(mMessageId));
                 carrierSendCompleteCallback.onSendMmsComplete(
                         CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
diff --git a/src/com/android/mms/service/metrics/MmsMetricsCollector.java b/src/com/android/mms/service/metrics/MmsMetricsCollector.java
new file mode 100644
index 0000000..8da61ba
--- /dev/null
+++ b/src/com/android/mms/service/metrics/MmsMetricsCollector.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import static com.android.mms.MmsStatsLog.INCOMING_MMS;
+import static com.android.mms.MmsStatsLog.OUTGOING_MMS;
+
+import android.app.StatsManager;
+import android.content.Context;
+import android.util.Log;
+import android.util.StatsEvent;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.mms.IncomingMms;
+import com.android.mms.MmsStatsLog;
+import com.android.mms.OutgoingMms;
+import com.android.internal.util.ConcurrentUtils;
+
+import java.time.Duration;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Implements statsd pullers for Mms.
+ *
+ * <p>This class registers pullers to statsd, which will be called once a day to obtain mms
+ * statistics that cannot be sent to statsd in real time.
+ */
+public class MmsMetricsCollector implements StatsManager.StatsPullAtomCallback {
+    private static final String TAG = MmsMetricsCollector.class.getSimpleName();
+    /** Disables various restrictions to ease debugging during development. */
+    private static final boolean DBG = false; // STOPSHIP if true
+    private static final long MILLIS_PER_HOUR = Duration.ofHours(1).toMillis();
+    private static final long MILLIS_PER_SECOND = Duration.ofSeconds(1).toMillis();
+    /**
+     * Sets atom pull cool down to 23 hours to help enforcing privacy requirement.
+     *
+     * <p>Applies to certain atoms. The interval of 23 hours leaves some margin for pull operations
+     * that occur once a day.
+     */
+    private static final long MIN_COOLDOWN_MILLIS =
+            DBG ? 10L * MILLIS_PER_SECOND : 23L * MILLIS_PER_HOUR;
+    private final PersistMmsAtomsStorage mStorage;
+    private final StatsManager mStatsManager;
+
+
+    public MmsMetricsCollector(Context context) {
+        this(context, new PersistMmsAtomsStorage(context));
+    }
+
+    @VisibleForTesting
+    public MmsMetricsCollector(Context context, PersistMmsAtomsStorage storage) {
+        mStorage = storage;
+        mStatsManager = context.getSystemService(StatsManager.class);
+        if (mStatsManager != null) {
+            registerAtom(INCOMING_MMS);
+            registerAtom(OUTGOING_MMS);
+            Log.d(TAG, "[MmsMetricsCollector]: registered atoms");
+        } else {
+            Log.e(TAG, "[MmsMetricsCollector]: could not get StatsManager, "
+                    + "atoms not registered");
+        }
+    }
+
+    private static StatsEvent buildStatsEvent(IncomingMms mms) {
+        return MmsStatsLog.buildStatsEvent(
+                INCOMING_MMS,
+                mms.getRat(),
+                mms.getResult(),
+                mms.getRoaming(),
+                mms.getSimSlotIndex(),
+                mms.getIsMultiSim(),
+                mms.getIsEsim(),
+                mms.getCarrierId(),
+                mms.getAvgIntervalMillis(),
+                mms.getMmsCount(),
+                mms.getRetryId(),
+                mms.getHandledByCarrierApp(),
+                mms.getIsManagedProfile());
+    }
+
+    private static StatsEvent buildStatsEvent(OutgoingMms mms) {
+        return MmsStatsLog.buildStatsEvent(
+                OUTGOING_MMS,
+                mms.getRat(),
+                mms.getResult(),
+                mms.getRoaming(),
+                mms.getSimSlotIndex(),
+                mms.getIsMultiSim(),
+                mms.getIsEsim(),
+                mms.getCarrierId(),
+                mms.getAvgIntervalMillis(),
+                mms.getMmsCount(),
+                mms.getIsFromDefaultApp(),
+                mms.getRetryId(),
+                mms.getHandledByCarrierApp(),
+                mms.getIsManagedProfile());
+    }
+
+    @Override
+    public int onPullAtom(int atomTag, List<StatsEvent> data) {
+        switch (atomTag) {
+            case INCOMING_MMS:
+                return pullIncomingMms(data);
+            case OUTGOING_MMS:
+                return pullOutgoingMms(data);
+            default:
+                Log.e(TAG, String.format("unexpected atom ID %d", atomTag));
+                return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullIncomingMms(List<StatsEvent> data) {
+        List<IncomingMms> incomingMmsList = mStorage.getIncomingMms(MIN_COOLDOWN_MILLIS);
+        if (incomingMmsList != null) {
+            // MMS List is already shuffled when MMS were inserted.
+            incomingMmsList.forEach(mms -> data.add(buildStatsEvent(mms)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Log.w(TAG, "INCOMING_MMS pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    private int pullOutgoingMms(List<StatsEvent> data) {
+        List<OutgoingMms> outgoingMmsList = mStorage.getOutgoingMms(MIN_COOLDOWN_MILLIS);
+        if (outgoingMmsList != null) {
+            // MMS List is already shuffled when MMS were inserted.
+            outgoingMmsList.forEach(mms -> data.add(buildStatsEvent(mms)));
+            return StatsManager.PULL_SUCCESS;
+        } else {
+            Log.w(TAG, "OUTGOING_MMS pull too frequent, skipping");
+            return StatsManager.PULL_SKIP;
+        }
+    }
+
+    /** Registers a pulled atom ID {@code atomId}. */
+    private void registerAtom(int atomId) {
+        mStatsManager.setPullAtomCallback(atomId, /* metadata= */ null,
+                ConcurrentUtils.DIRECT_EXECUTOR, this);
+    }
+
+    /** Returns the {@link PersistMmsAtomsStorage} backing the puller. */
+    public PersistMmsAtomsStorage getAtomsStorage() {
+        return mStorage;
+    }
+}
diff --git a/src/com/android/mms/service/metrics/MmsStats.java b/src/com/android/mms/service/metrics/MmsStats.java
new file mode 100644
index 0000000..7e98b0b
--- /dev/null
+++ b/src/com/android/mms/service/metrics/MmsStats.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import static com.android.mms.MmsStatsLog.INCOMING_MMS__RESULT__MMS_RESULT_ERROR_UNSPECIFIED;
+import static com.android.mms.MmsStatsLog.INCOMING_MMS__RESULT__MMS_RESULT_SUCCESS;
+import static com.android.mms.MmsStatsLog.OUTGOING_MMS__RESULT__MMS_RESULT_ERROR_UNSPECIFIED;
+import static com.android.mms.MmsStatsLog.OUTGOING_MMS__RESULT__MMS_RESULT_SUCCESS;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Binder;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.telephony.ServiceState;
+import android.telephony.SmsManager;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.telephony.UiccCardInfo;
+
+import com.android.internal.telephony.SmsApplication;
+import com.android.mms.IncomingMms;
+import com.android.mms.OutgoingMms;
+
+import java.util.List;
+
+/** Collects mms events for the pulled atom. */
+public class MmsStats {
+    private static final String TAG = MmsStats.class.getSimpleName();
+
+    private final Context mContext;
+    private final PersistMmsAtomsStorage mPersistMmsAtomsStorage;
+    private final String mCallingPkg;
+    private final boolean mIsIncomingMms;
+    private final long mTimestamp;
+    private int mSubId;
+    private TelephonyManager mTelephonyManager;
+
+    public MmsStats(Context context, PersistMmsAtomsStorage persistMmsAtomsStorage, int subId,
+            TelephonyManager telephonyManager, String callingPkg, boolean isIncomingMms) {
+        mContext = context;
+        mPersistMmsAtomsStorage = persistMmsAtomsStorage;
+        mSubId = subId;
+        mTelephonyManager = telephonyManager;
+        mCallingPkg = callingPkg;
+        mIsIncomingMms = isIncomingMms;
+        mTimestamp = SystemClock.elapsedRealtime();
+    }
+
+    /** Updates subId and corresponding telephonyManager. */
+    public void updateSubId(int subId, TelephonyManager telephonyManager) {
+        mSubId = subId;
+        mTelephonyManager = telephonyManager;
+    }
+
+    /** Adds incoming or outgoing mms atom to storage. */
+    public void addAtomToStorage(int result) {
+        addAtomToStorage(result, 0, false);
+    }
+
+    /** Adds incoming or outgoing mms atom to storage. */
+    public void addAtomToStorage(int result, int retryId, boolean handledByCarrierApp) {
+        long identity = Binder.clearCallingIdentity();
+        try {
+            if (mIsIncomingMms) {
+                onIncomingMms(result, retryId, handledByCarrierApp);
+            } else {
+                onOutgoingMms(result, retryId, handledByCarrierApp);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /** Creates a new atom when MMS is received. */
+    private void onIncomingMms(int result, int retryId, boolean handledByCarrierApp) {
+        IncomingMms incomingMms = IncomingMms.newBuilder()
+                .setRat(getDataNetworkType())
+                .setResult(getIncomingMmsResult(result))
+                .setRoaming(getDataRoamingType())
+                .setSimSlotIndex(getSlotIndex())
+                .setIsMultiSim(getIsMultiSim())
+                .setIsEsim(getIsEuicc())
+                .setCarrierId(getSimCarrierId())
+                .setAvgIntervalMillis(getInterval())
+                .setMmsCount(1)
+                .setRetryId(retryId)
+                .setHandledByCarrierApp(handledByCarrierApp)
+                .setIsManagedProfile(isManagedProfile())
+                .build();
+        mPersistMmsAtomsStorage.addIncomingMms(incomingMms);
+    }
+
+    /** Creates a new atom when MMS is sent. */
+    private void onOutgoingMms(int result, int retryId, boolean handledByCarrierApp) {
+        OutgoingMms outgoingMms = OutgoingMms.newBuilder()
+                .setRat(getDataNetworkType())
+                .setResult(getOutgoingMmsResult(result))
+                .setRoaming(getDataRoamingType())
+                .setSimSlotIndex(getSlotIndex())
+                .setIsMultiSim(getIsMultiSim())
+                .setIsEsim(getIsEuicc())
+                .setCarrierId(getSimCarrierId())
+                .setAvgIntervalMillis(getInterval())
+                .setMmsCount(1)
+                .setIsFromDefaultApp(isDefaultMmsApp())
+                .setRetryId(retryId)
+                .setHandledByCarrierApp(handledByCarrierApp)
+                .setIsManagedProfile(isManagedProfile())
+                .build();
+        mPersistMmsAtomsStorage.addOutgoingMms(outgoingMms);
+    }
+
+    /** @return {@code true} if this SIM is dedicated to work profile */
+    private boolean isManagedProfile() {
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        if (subManager == null || !subManager.isActiveSubscriptionId(mSubId)) return false;
+        UserHandle userHandle = subManager.getSubscriptionUserHandle(mSubId);
+        UserManager userManager = mContext.getSystemService(UserManager.class);
+        if (userHandle == null || userManager == null) return false;
+        return userManager.isManagedProfile(userHandle.getIdentifier());
+    }
+
+    /** Returns data network type of current subscription. */
+    private int getDataNetworkType() {
+        return mTelephonyManager.getDataNetworkType();
+    }
+
+    /** Returns incoming mms result. */
+    private int getIncomingMmsResult(int result) {
+        switch (result) {
+            case SmsManager.MMS_ERROR_UNSPECIFIED:
+                // SmsManager.MMS_ERROR_UNSPECIFIED(1) -> MMS_RESULT_ERROR_UNSPECIFIED(0)
+                return INCOMING_MMS__RESULT__MMS_RESULT_ERROR_UNSPECIFIED;
+            case Activity.RESULT_OK:
+                // Activity.RESULT_OK -> MMS_RESULT_SUCCESS(1)
+                return INCOMING_MMS__RESULT__MMS_RESULT_SUCCESS;
+            default:
+                // Int value of other SmsManager.MMS_ERROR matches MMS_RESULT_ERROR
+                return result;
+        }
+    }
+
+    /** Returns outgoing mms result. */
+    private int getOutgoingMmsResult(int result) {
+        switch (result) {
+            case SmsManager.MMS_ERROR_UNSPECIFIED:
+                // SmsManager.MMS_ERROR_UNSPECIFIED(1) -> MMS_RESULT_ERROR_UNSPECIFIED(0)
+                return OUTGOING_MMS__RESULT__MMS_RESULT_ERROR_UNSPECIFIED;
+            case Activity.RESULT_OK:
+                // Activity.RESULT_OK -> MMS_RESULT_SUCCESS(1)
+                return OUTGOING_MMS__RESULT__MMS_RESULT_SUCCESS;
+            default:
+                // Int value of other SmsManager.MMS_ERROR matches MMS_RESULT_ERROR
+                return result;
+        }
+    }
+
+    /** Returns data network roaming type of current subscription. */
+    private int getDataRoamingType() {
+        ServiceState serviceState = mTelephonyManager.getServiceState();
+        return (serviceState != null) ? serviceState.getDataRoamingType() :
+                ServiceState.ROAMING_TYPE_NOT_ROAMING;
+    }
+
+    /** Returns slot index associated with the subscription. */
+    private int getSlotIndex() {
+        return SubscriptionManager.getSlotIndex(mSubId);
+    }
+
+    /** Returns whether the device has multiple active SIM profiles. */
+    private boolean getIsMultiSim() {
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        if(subManager == null) {
+            return false;
+        }
+
+        List<SubscriptionInfo> activeSubscriptionInfo = subManager.getActiveSubscriptionInfoList();
+        return (activeSubscriptionInfo.size() > 1);
+    }
+
+    /** Returns if current subscription is embedded subscription. */
+    private boolean getIsEuicc() {
+        List<UiccCardInfo> uiccCardInfoList = mTelephonyManager.getUiccCardsInfo();
+        for (UiccCardInfo card : uiccCardInfoList) {
+            if (card.getPhysicalSlotIndex() == getSlotIndex()) {
+                return card.isEuicc();
+            }
+        }
+        return false;
+    }
+
+    /** Returns carrier id of the current subscription used by MMS. */
+    private int getSimCarrierId() {
+        return mTelephonyManager.getSimCarrierId();
+    }
+
+    /** Returns if the MMS was originated from the default MMS application. */
+    private boolean isDefaultMmsApp() {
+        UserHandle userHandle = null;
+        SubscriptionManager subManager = mContext.getSystemService(SubscriptionManager.class);
+        if ((subManager != null) && (subManager.isActiveSubscriptionId(mSubId))) {
+            userHandle = subManager.getSubscriptionUserHandle(mSubId);
+        }
+        return SmsApplication.isDefaultMmsApplicationAsUser(mContext, mCallingPkg, userHandle);
+    }
+
+    /**
+     * Returns the interval in milliseconds between sending/receiving MMS message and current time.
+     * Calculates the time taken to send message to the network
+     * or download message from the network.
+     */
+    private long getInterval() {
+        return (SystemClock.elapsedRealtime() - mTimestamp);
+    }
+}
diff --git a/src/com/android/mms/service/metrics/PersistMmsAtomsStorage.java b/src/com/android/mms/service/metrics/PersistMmsAtomsStorage.java
new file mode 100644
index 0000000..4e9ffc7
--- /dev/null
+++ b/src/com/android/mms/service/metrics/PersistMmsAtomsStorage.java
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
+
+import com.android.mms.IncomingMms;
+import com.android.mms.OutgoingMms;
+import com.android.mms.PersistMmsAtoms;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class PersistMmsAtomsStorage {
+    private static final String TAG = PersistMmsAtomsStorage.class.getSimpleName();
+
+    /** Name of the file where cached statistics are saved to. */
+    private static final String FILENAME = "persist_mms_atoms.pb";
+
+    /** Delay to store atoms to persistent storage to bundle multiple operations together. */
+    private static final int SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS = 30000;
+
+    /**
+     * Delay to store atoms to persistent storage during pulls to avoid unnecessary operations.
+     *
+     * <p>This delay should be short to avoid duplicating atoms or losing pull timestamp in case of
+     * crash or power loss.
+     */
+    private static final int SAVE_TO_FILE_DELAY_FOR_GET_MILLIS = 500;
+    private static final SecureRandom sRandom = new SecureRandom();
+    /**
+     * Maximum number of MMS to store between pulls.
+     * Incoming MMS and outgoing MMS are counted separately.
+     */
+    private final int mMaxNumMms;
+    private final Context mContext;
+    private final Handler mHandler;
+    private final HandlerThread mHandlerThread;
+    /** Stores persist atoms and persist states of the puller. */
+    @VisibleForTesting
+    protected PersistMmsAtoms mPersistMmsAtoms;
+    private final Runnable mSaveRunnable =
+            new Runnable() {
+                @Override
+                public void run() {
+                    saveAtomsToFileNow();
+                }
+            };
+    /** Whether atoms should be saved immediately, skipping the delay. */
+    @VisibleForTesting
+    protected boolean mSaveImmediately;
+
+    public PersistMmsAtomsStorage(Context context) {
+        mContext = context;
+
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_RAM_LOW)) {
+            Log.i(TAG, "[PersistMmsAtomsStorage]: Low RAM device");
+            mMaxNumMms = 5;
+        } else {
+            mMaxNumMms = 25;
+        }
+        mPersistMmsAtoms = loadAtomsFromFile();
+        mHandlerThread = new HandlerThread("PersistMmsAtomsThread");
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mSaveImmediately = false;
+    }
+
+    /** Loads {@link  PersistMmsAtoms} from a file in private storage. */
+    private PersistMmsAtoms loadAtomsFromFile() {
+        try {
+            PersistMmsAtoms atoms = PersistMmsAtoms.parseFrom(
+                    Files.readAllBytes(mContext.getFileStreamPath(FILENAME).toPath()));
+
+            // Start from scratch if build changes, since mixing atoms from different builds could
+            // produce strange results.
+            if (!Build.FINGERPRINT.equals(atoms.getBuildFingerprint())) {
+                Log.d(TAG, "[loadAtomsFromFile]: Build changed");
+                return makeNewPersistMmsAtoms();
+            }
+            // check all the fields in case of situations such as OTA or crash during saving.
+            List<IncomingMms> incomingMms = sanitizeAtoms(atoms.getIncomingMmsList(), mMaxNumMms);
+            List<OutgoingMms> outgoingMms = sanitizeAtoms(atoms.getOutgoingMmsList(), mMaxNumMms);
+            long incomingMmsPullTimestamp = sanitizeTimestamp(
+                    atoms.getIncomingMmsPullTimestampMillis());
+            long outgoingMmsPullTimestamp = sanitizeTimestamp(
+                    atoms.getOutgoingMmsPullTimestampMillis());
+
+            // Rebuild atoms after sanitizing.
+            atoms = atoms.toBuilder()
+                    .clearIncomingMms()
+                    .clearOutgoingMms()
+                    .addAllIncomingMms(incomingMms)
+                    .addAllOutgoingMms(outgoingMms)
+                    .setIncomingMmsPullTimestampMillis(incomingMmsPullTimestamp)
+                    .setOutgoingMmsPullTimestampMillis(outgoingMmsPullTimestamp)
+                    .build();
+            return atoms;
+        } catch (NoSuchFileException e) {
+            Log.e(TAG, "[loadAtomsFromFile]: PersistMmsAtoms file not found");
+        } catch (IOException | NullPointerException e) {
+            Log.e(TAG, "[loadAtomsFromFile]: cannot load/parse PersistMmsAtoms", e);
+        }
+        return makeNewPersistMmsAtoms();
+    }
+
+    /** Adds an IncomingMms to the storage. */
+    public synchronized void addIncomingMms(IncomingMms mms) {
+        int existingMmsIndex = findIndex(mms);
+        if (existingMmsIndex != -1) {
+            // Update mmsCount and avgIntervalMillis of existingMms.
+            IncomingMms existingMms = mPersistMmsAtoms.getIncomingMms(existingMmsIndex);
+            long updatedMmsCount = existingMms.getMmsCount() + 1;
+            long updatedAvgIntervalMillis =
+                    (((existingMms.getAvgIntervalMillis() * existingMms.getMmsCount())
+                            + mms.getAvgIntervalMillis()) / updatedMmsCount);
+            existingMms = existingMms.toBuilder()
+                    .setMmsCount(updatedMmsCount)
+                    .setAvgIntervalMillis(updatedAvgIntervalMillis)
+                    .build();
+
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .setIncomingMms(existingMmsIndex, existingMms)
+                    .build();
+        } else {
+            // Insert new mms at random place.
+            List<IncomingMms> incomingMmsList = insertAtRandomPlace(
+                    mPersistMmsAtoms.getIncomingMmsList(), mms, mMaxNumMms);
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .clearIncomingMms()
+                    .addAllIncomingMms(incomingMmsList)
+                    .build();
+        }
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /** Adds an OutgoingMms to the storage. */
+    public synchronized void addOutgoingMms(OutgoingMms mms) {
+        int existingMmsIndex = findIndex(mms);
+        if (existingMmsIndex != -1) {
+            // Update mmsCount and avgIntervalMillis of existingMms.
+            OutgoingMms existingMms = mPersistMmsAtoms.getOutgoingMms(existingMmsIndex);
+            long updatedMmsCount = existingMms.getMmsCount() + 1;
+            long updatedAvgIntervalMillis =
+                    (((existingMms.getAvgIntervalMillis() * existingMms.getMmsCount())
+                            + mms.getAvgIntervalMillis()) / updatedMmsCount);
+            existingMms = existingMms.toBuilder()
+                    .setMmsCount(updatedMmsCount)
+                    .setAvgIntervalMillis(updatedAvgIntervalMillis)
+                    .build();
+
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .setOutgoingMms(existingMmsIndex, existingMms)
+                    .build();
+        } else {
+            // Insert new mms at random place.
+            List<OutgoingMms> outgoingMmsList = insertAtRandomPlace(
+                    mPersistMmsAtoms.getOutgoingMmsList(), mms, mMaxNumMms);
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .clearOutgoingMms()
+                    .addAllOutgoingMms(outgoingMmsList)
+                    .build();
+        }
+        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
+    }
+
+    /**
+     * Returns and clears the IncomingMms if last pulled longer than {@code minIntervalMillis} ago,
+     * otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized List<IncomingMms> getIncomingMms(long minIntervalMillis) {
+        if ((getWallTimeMillis() - mPersistMmsAtoms.getIncomingMmsPullTimestampMillis())
+                > minIntervalMillis) {
+            List<IncomingMms> previousIncomingMmsList = mPersistMmsAtoms.getIncomingMmsList();
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .setIncomingMmsPullTimestampMillis(getWallTimeMillis())
+                    .clearIncomingMms()
+                    .build();
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return previousIncomingMmsList;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns and clears the OutgoingMms if last pulled longer than {@code minIntervalMillis} ago,
+     * otherwise returns {@code null}.
+     */
+    @Nullable
+    public synchronized List<OutgoingMms> getOutgoingMms(long minIntervalMillis) {
+        if ((getWallTimeMillis() - mPersistMmsAtoms.getOutgoingMmsPullTimestampMillis())
+                > minIntervalMillis) {
+            List<OutgoingMms> previousOutgoingMmsList = mPersistMmsAtoms.getOutgoingMmsList();
+            mPersistMmsAtoms = mPersistMmsAtoms.toBuilder()
+                    .setOutgoingMmsPullTimestampMillis(getWallTimeMillis())
+                    .clearOutgoingMms()
+                    .build();
+            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
+            return previousOutgoingMmsList;
+        } else {
+            return null;
+        }
+    }
+
+    /** Saves a pending {@link PersistMmsAtoms} to a file in private storage immediately. */
+    public void flushAtoms() {
+        if (mHandler.hasCallbacks(mSaveRunnable)) {
+            mHandler.removeCallbacks(mSaveRunnable);
+            saveAtomsToFileNow();
+        }
+    }
+
+    /** Returns an empty PersistMmsAtoms with pull timestamp set to current time. */
+    private PersistMmsAtoms makeNewPersistMmsAtoms() {
+        // allow pulling only after some time so data are sufficiently aggregated.
+        long currentTime = getWallTimeMillis();
+        PersistMmsAtoms atoms = PersistMmsAtoms.newBuilder()
+                .setBuildFingerprint(Build.FINGERPRINT)
+                .setIncomingMmsPullTimestampMillis(currentTime)
+                .setOutgoingMmsPullTimestampMillis(currentTime)
+                .build();
+        return atoms;
+    }
+
+    /**
+     * Posts message to save a copy of {@link PersistMmsAtoms} to a file after a delay.
+     *
+     * <p>The delay is introduced to avoid too frequent operations to disk, which would negatively
+     * impact the power consumption.
+     */
+    private void saveAtomsToFile(int delayMillis) {
+        if (delayMillis > 0 && !mSaveImmediately) {
+            mHandler.removeCallbacks(mSaveRunnable);
+            if (mHandler.postDelayed(mSaveRunnable, delayMillis)) {
+                return;
+            }
+        }
+        // In case of error posting the event or if delay is 0, save immediately.
+        saveAtomsToFileNow();
+    }
+
+    /** Saves a copy of {@link PersistMmsAtoms} to a file in private storage. */
+    private synchronized void saveAtomsToFileNow() {
+        try (FileOutputStream stream = mContext.openFileOutput(FILENAME, Context.MODE_PRIVATE)) {
+            stream.write(mPersistMmsAtoms.toByteArray());
+        } catch (IOException e) {
+            Log.e(TAG, "[saveAtomsToFileNow]: Cannot save PersistMmsAtoms", e);
+        }
+    }
+
+    /**
+     * Inserts a new element in a random position.
+     */
+    private static <T> List<T> insertAtRandomPlace(List<T> storage, T instance, int maxSize) {
+        final int storage_size = storage.size();
+        List<T> result = new ArrayList<>(storage);
+        if (storage_size == 0) {
+            result.add(instance);
+        } else if (storage_size == maxSize) {
+            // Index of the item suitable for eviction is chosen randomly when the array is full.
+            int insertAt = sRandom.nextInt(maxSize);
+            result.set(insertAt, instance);
+        } else {
+            // Insert at random place (by moving the item at the random place to the end).
+            int insertAt = sRandom.nextInt(storage_size);
+            result.add(result.get(insertAt));
+            result.set(insertAt, instance);
+        }
+        return result;
+    }
+
+    /**
+     * Returns IncomingMms atom index that has the same dimension values with the given one,
+     * or {@code -1} if it does not exist.
+     */
+    private int findIndex(IncomingMms key) {
+        for (int i = 0; i < mPersistMmsAtoms.getIncomingMmsCount(); i++) {
+            IncomingMms mms = mPersistMmsAtoms.getIncomingMms(i);
+            if (mms.getRat() == key.getRat()
+                    && mms.getResult() == key.getResult()
+                    && mms.getRoaming() == key.getRoaming()
+                    && mms.getSimSlotIndex() == key.getSimSlotIndex()
+                    && mms.getIsMultiSim() == key.getIsMultiSim()
+                    && mms.getIsEsim() == key.getIsEsim()
+                    && mms.getCarrierId() == key.getCarrierId()
+                    && mms.getRetryId() == key.getRetryId()
+                    && mms.getHandledByCarrierApp() == key.getHandledByCarrierApp()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Returns OutgoingMms atom index that has the same dimension values with the given one,
+     * or {@code -1} if it does not exist.
+     */
+    private int findIndex(OutgoingMms key) {
+        for (int i = 0; i < mPersistMmsAtoms.getOutgoingMmsCount(); i++) {
+            OutgoingMms mms = mPersistMmsAtoms.getOutgoingMms(i);
+            if (mms.getRat() == key.getRat()
+                    && mms.getResult() == key.getResult()
+                    && mms.getRoaming() == key.getRoaming()
+                    && mms.getSimSlotIndex() == key.getSimSlotIndex()
+                    && mms.getIsMultiSim() == key.getIsMultiSim()
+                    && mms.getIsEsim() == key.getIsEsim()
+                    && mms.getCarrierId() == key.getCarrierId()
+                    && mms.getIsFromDefaultApp() == key.getIsFromDefaultApp()
+                    && mms.getRetryId() == key.getRetryId()
+                    && mms.getHandledByCarrierApp() == key.getHandledByCarrierApp()) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /** Sanitizes the loaded list of atoms to avoid null values. */
+    private <T> List<T> sanitizeAtoms(List<T> list) {
+        return list == null ? Collections.emptyList() : list;
+    }
+
+    /** Sanitizes the loaded list of atoms loaded to avoid null values and enforce max length. */
+    private <T> List<T> sanitizeAtoms(List<T> list, int maxSize) {
+        list = sanitizeAtoms(list);
+        if (list.size() > maxSize) {
+            return list.subList(0, maxSize);
+        }
+        return list;
+    }
+
+    /** Sanitizes the timestamp of the last pull loaded from persistent storage. */
+    private long sanitizeTimestamp(long timestamp) {
+        return timestamp <= 0L ? getWallTimeMillis() : timestamp;
+    }
+
+    @VisibleForTesting
+    protected long getWallTimeMillis() {
+        // Epoch time in UTC, preserved across reboots, but can be adjusted e.g. by the user or NTP.
+        return System.currentTimeMillis();
+    }
+}
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/mms/service/MmsNetworkManagerTest.java b/tests/robotests/src/com/android/mms/service/MmsNetworkManagerTest.java
index c2d3e05..dff2bab 100644
--- a/tests/robotests/src/com/android/mms/service/MmsNetworkManagerTest.java
+++ b/tests/robotests/src/com/android/mms/service/MmsNetworkManagerTest.java
@@ -36,6 +36,8 @@
 import android.net.Network;
 import android.net.NetworkCapabilities;
 import android.net.NetworkInfo;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -70,7 +72,8 @@
     @Mock Context mCtx;
     @Mock ConnectivityManager mCm;
     @Mock MmsNetworkManager.Dependencies mDeps;
-
+    @Mock CarrierConfigManager mCarrierConfigManager;
+    @Mock PersistableBundle mConfig;
 
     private MmsNetworkManager mMnm;
     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
@@ -89,6 +92,8 @@
         doReturn(MMS_APN2).when(mNetworkInfo2).getExtraInfo();
         doReturn(NETWORK_ACQUIRE_TIMEOUT_MS).when(mDeps).getNetworkRequestTimeoutMillis();
         doReturn(NETWORK_ACQUIRE_TIMEOUT_MS).when(mDeps).getAdditionalNetworkAcquireTimeoutMillis();
+        doReturn(mCarrierConfigManager).when(mCtx).getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        doReturn(mConfig).when(mCarrierConfigManager).getConfigForSubId(TEST_SUBID);
 
         mMnm = new MmsNetworkManager(mCtx, TEST_SUBID, mDeps);
     }
@@ -201,6 +206,25 @@
         assertEquals(null, mMnm.getApnName());
     }
 
+    @Test
+    public void testHandleCarrierConfigChanged() throws Exception {
+        // Expect receiving default NETWORK_RELEASE_TIMEOUT of 5 seconds
+        int defaultNetworkReleaseTimeout = 5000;
+        doReturn(defaultNetworkReleaseTimeout).when(mConfig).getInt(
+                CarrierConfigManager.KEY_MMS_NETWORK_RELEASE_TIMEOUT_MILLIS_INT);
+        MmsNetworkManager mmsNetworkManager = new MmsNetworkManager(mCtx, TEST_SUBID, mDeps);
+        assertEquals(defaultNetworkReleaseTimeout,
+                mmsNetworkManager.getNetworkReleaseTimeoutMillis());
+
+        // Expect receiving a carrier-configured value
+        int configuredNetworkReleaseTimeout = 10000;
+        doReturn(configuredNetworkReleaseTimeout).when(mConfig).getInt(
+                CarrierConfigManager.KEY_MMS_NETWORK_RELEASE_TIMEOUT_MILLIS_INT);
+        mmsNetworkManager = new MmsNetworkManager(mCtx, TEST_SUBID, mDeps);
+        assertEquals(configuredNetworkReleaseTimeout,
+                mmsNetworkManager.getNetworkReleaseTimeoutMillis());
+    }
+
     private NetworkCallback acquireAvailableNetworkAndGetCallback(
             Network expectNetwork, String expectApn) throws Exception {
         final ArgumentCaptor<NetworkCallback> callbackCaptor =
diff --git a/tests/unittests/Android.bp b/tests/unittests/Android.bp
new file mode 100644
index 0000000..595b4be
--- /dev/null
+++ b/tests/unittests/Android.bp
@@ -0,0 +1,27 @@
+package {
+    // See: http://go/android-license-faq
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "MmsServiceTests",
+    static_libs: [
+        "mms-protos-lite",
+        "mms-statsd",
+        "androidx.annotation_annotation",
+        "mockito-target",
+        "compatibility-device-util-axt",
+        "androidx.test.rules",
+        "truth-prebuilt",
+    ],
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+        "android.test.mock",
+    ],
+    srcs: ["src/**/*.java", ":mms-service-srcs"],
+    platform_apis: true,
+    test_suites: ["device-tests"],
+    certificate: "platform",
+    instrumentation_for: "MmsService",
+}
diff --git a/tests/unittests/AndroidManifest.xml b/tests/unittests/AndroidManifest.xml
new file mode 100644
index 0000000..3b4b582
--- /dev/null
+++ b/tests/unittests/AndroidManifest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.mms.service.tests"
+          android:debuggable="true"
+          android:sharedUserId="android.uid.phone">
+
+    <application>
+        <uses-library android:name="android.test.runner"/>
+    </application>
+
+    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.mms.service.tests"
+                     android:label="MmsServiceTests"
+                     android:debuggable="true">
+    </instrumentation>
+</manifest>
\ No newline at end of file
diff --git a/tests/unittests/AndroidTest.xml b/tests/unittests/AndroidTest.xml
new file mode 100644
index 0000000..61b3f5d
--- /dev/null
+++ b/tests/unittests/AndroidTest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2022 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<configuration description="Run MmsServiceTests.">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="MmsServiceTests.apk"/>
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="MmsServiceTests"/>
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="com.android.mms.service.tests"/>
+        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner"/>
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
\ No newline at end of file
diff --git a/tests/unittests/src/com/android/mms/service/MmsHttpClientTest.java b/tests/unittests/src/com/android/mms/service/MmsHttpClientTest.java
new file mode 100644
index 0000000..dd126e8
--- /dev/null
+++ b/tests/unittests/src/com/android/mms/service/MmsHttpClientTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.os.Bundle;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.After;
+import org.junit.Before;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+import org.junit.Test;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.reset;
+
+import android.util.Log;
+
+public class MmsHttpClientTest {
+    // Mocked classes
+    private Context mContext;
+    private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
+
+    // The raw phone number from TelephonyManager.getLine1Number
+    private static final String MACRO_LINE1 = "LINE1";
+    // The phone number without country code
+    private static final String MACRO_LINE1NOCOUNTRYCODE = "LINE1NOCOUNTRYCODE";
+    private String line1Number = "1234567890";
+    private String subscriberPhoneNumber = "0987654321";
+    private int subId = 1;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mTelephonyManager = mock(TelephonyManager.class);
+        mSubscriptionManager = mock(SubscriptionManager.class);
+
+        when(mContext.getSystemService(Context.TELEPHONY_SERVICE))
+            .thenReturn(mTelephonyManager);
+        when(mTelephonyManager.createForSubscriptionId(anyInt()))
+            .thenReturn(mTelephonyManager);
+        when(mContext.getSystemService(SubscriptionManager.class))
+            .thenReturn(mSubscriptionManager);
+    }
+
+    @After
+    public void tearDown() {
+        mContext = null;
+        mTelephonyManager = null;
+        mSubscriptionManager = null;
+    }
+
+    @Test
+    public void getPhoneNumberForMacroLine1() {
+        String macro = MACRO_LINE1;
+        Bundle mmsConfig = new Bundle();
+        String emptyStr = "";
+        String phoneNo;
+
+        /* when getLine1Number returns valid number */
+        doReturn(line1Number).when(mTelephonyManager).getLine1Number();
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).isEqualTo(line1Number);
+        // getLine1NumberAPI should be called
+        verify(mTelephonyManager).getLine1Number();
+        // getPhoneNumber should never be called
+        verify(mSubscriptionManager, never()).getPhoneNumber(subId);
+
+        /* when getLine1Number returns empty string */
+        doReturn(emptyStr).when(mTelephonyManager).getLine1Number();
+        when(mSubscriptionManager.getPhoneNumber(subId)).thenReturn(subscriberPhoneNumber);
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).isEqualTo(subscriberPhoneNumber);
+        verify(mSubscriptionManager).getPhoneNumber(subId);
+
+        /* when getLine1Number returns null */
+        reset(mSubscriptionManager);
+        when(mSubscriptionManager.getPhoneNumber(subId)).thenReturn(subscriberPhoneNumber);
+        doReturn(null).when(mTelephonyManager).getLine1Number();
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).isEqualTo(subscriberPhoneNumber);
+        verify(mSubscriptionManager).getPhoneNumber(subId);
+    }
+
+    @Test
+    public void getPhoneNumberForMacroLine1CountryCode() throws Exception {
+        String macro = MACRO_LINE1NOCOUNTRYCODE;
+        String emptyStr = "";
+        String phoneNo;
+        Bundle mmsConfig = new Bundle();
+
+        /* when getLine1Number returns valid number */
+        doReturn(line1Number).when(mTelephonyManager).getLine1Number();
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).contains(line1Number);
+        // getLine1NumberAPI should be called
+        verify(mTelephonyManager).getLine1Number();
+        // getPhoneNumber should never be called
+        verify(mSubscriptionManager, never()).getPhoneNumber(subId);
+
+        /* when getLine1Number returns empty string */
+        doReturn(emptyStr).when(mTelephonyManager).getLine1Number();
+        when(mSubscriptionManager.getPhoneNumber(subId)).thenReturn(subscriberPhoneNumber);
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).contains(subscriberPhoneNumber);
+        verify(mSubscriptionManager).getPhoneNumber(subId);
+
+        /* when getLine1Number returns null */
+        reset(mSubscriptionManager);
+        when(mSubscriptionManager.getPhoneNumber(subId)).thenReturn(subscriberPhoneNumber);
+        doReturn(null).when(mTelephonyManager).getLine1Number();
+        phoneNo = MmsHttpClient.getMacroValue(mContext, macro, mmsConfig, subId);
+        assertThat(phoneNo).contains(subscriberPhoneNumber);
+        verify(mSubscriptionManager).getPhoneNumber(subId);
+    }
+}
diff --git a/tests/unittests/src/com/android/mms/service/metrics/MmsMetricsCollectorTest.java b/tests/unittests/src/com/android/mms/service/metrics/MmsMetricsCollectorTest.java
new file mode 100644
index 0000000..8d93739
--- /dev/null
+++ b/tests/unittests/src/com/android/mms/service/metrics/MmsMetricsCollectorTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import static com.android.mms.MmsStatsLog.INCOMING_MMS;
+import static com.android.mms.MmsStatsLog.OUTGOING_MMS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.app.StatsManager;
+import android.content.Context;
+import android.util.StatsEvent;
+
+import com.android.mms.IncomingMms;
+import com.android.mms.OutgoingMms;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class MmsMetricsCollectorTest {
+    private static final long MIN_COOLDOWN_MILLIS = 23L * 3600L * 1000L;
+    Context mContext;
+    private PersistMmsAtomsStorage mPersistMmsAtomsStorage;
+    private MmsMetricsCollector mMmsMetricsCollector;
+
+    @Before
+    public void setUp() {
+        mContext = mock(Context.class);
+        mPersistMmsAtomsStorage = mock(PersistMmsAtomsStorage.class);
+        mMmsMetricsCollector = new MmsMetricsCollector(mContext, mPersistMmsAtomsStorage);
+    }
+
+    @After
+    public void tearDown() {
+        mContext = null;
+        mPersistMmsAtomsStorage = null;
+        mMmsMetricsCollector = null;
+    }
+
+    @Test
+    public void onPullAtom_incomingMms_empty() {
+        doReturn(new ArrayList<>()).when(mPersistMmsAtomsStorage).getIncomingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(INCOMING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
+
+    @Test
+    public void onPullAtom_incomingMms_tooFrequent() {
+        doReturn(null).when(mPersistMmsAtomsStorage).getIncomingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(INCOMING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SKIP);
+        verify(mPersistMmsAtomsStorage, times(1))
+                .getIncomingMms(eq(MIN_COOLDOWN_MILLIS));
+        verifyNoMoreInteractions(mPersistMmsAtomsStorage);
+    }
+
+    @Test
+    public void onPullAtom_incomingMms_multipleMms() {
+        IncomingMms incomingMms = IncomingMms.newBuilder().build();
+        doReturn(Arrays.asList(incomingMms, incomingMms, incomingMms, incomingMms))
+                .when(mPersistMmsAtomsStorage).getIncomingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(INCOMING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(4);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
+
+    @Test
+    public void onPullAtom_outgoingMms_empty() {
+        doReturn(new ArrayList<>()).when(mPersistMmsAtomsStorage).getOutgoingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(OUTGOING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
+
+    @Test
+    public void onPullAtom_outgoingMms_tooFrequent() {
+        doReturn(null).when(mPersistMmsAtomsStorage).getOutgoingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(OUTGOING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(0);
+        assertThat(result).isEqualTo(StatsManager.PULL_SKIP);
+        verify(mPersistMmsAtomsStorage, times(1))
+                .getOutgoingMms(eq(MIN_COOLDOWN_MILLIS));
+        verifyNoMoreInteractions(mPersistMmsAtomsStorage);
+    }
+
+    @Test
+    public void onPullAtom_outgoingMms_multipleMms() {
+        OutgoingMms outgoingMms = OutgoingMms.newBuilder().build();
+        doReturn(Arrays.asList(outgoingMms, outgoingMms, outgoingMms, outgoingMms))
+                .when(mPersistMmsAtomsStorage).getOutgoingMms(anyLong());
+        List<StatsEvent> actualAtoms = new ArrayList<>();
+
+        int result = mMmsMetricsCollector.onPullAtom(OUTGOING_MMS, actualAtoms);
+
+        assertThat(actualAtoms).hasSize(4);
+        assertThat(result).isEqualTo(StatsManager.PULL_SUCCESS);
+    }
+}
\ No newline at end of file
diff --git a/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java b/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java
new file mode 100644
index 0000000..2b2cae5
--- /dev/null
+++ b/tests/unittests/src/com/android/mms/service/metrics/MmsStatsTest.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import static com.android.mms.MmsStatsLog.INCOMING_MMS__RESULT__MMS_RESULT_SUCCESS;
+import static com.android.mms.MmsStatsLog.OUTGOING_MMS__RESULT__MMS_RESULT_SUCCESS;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.app.Activity;
+import android.content.Context;
+import android.telephony.ServiceState;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+
+import com.android.mms.IncomingMms;
+import com.android.mms.OutgoingMms;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.mockito.ArgumentCaptor;
+
+public class MmsStatsTest {
+    // Mocked classes
+    private Context mContext;
+    private PersistMmsAtomsStorage mPersistMmsAtomsStorage;
+    private TelephonyManager mTelephonyManager;
+    private SubscriptionManager mSubscriptionManager;
+
+    @Before
+    public void setUp() {
+        mContext = mock(Context.class);
+        mPersistMmsAtomsStorage = mock(PersistMmsAtomsStorage.class);
+        mTelephonyManager = mock(TelephonyManager.class);
+        mSubscriptionManager = mock(SubscriptionManager.class);
+
+        doReturn(mSubscriptionManager).when(mContext).getSystemService(
+                Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+    }
+
+    @After
+    public void tearDown() {
+        mContext = null;
+        mPersistMmsAtomsStorage = null;
+        mTelephonyManager = null;
+    }
+
+    @Test
+    public void addAtomToStorage_incomingMms_default() {
+        doReturn(null).when(mTelephonyManager).getServiceState();
+        doReturn(TelephonyManager.UNKNOWN_CARRIER_ID).when(mTelephonyManager).getSimCarrierId();
+        int inactiveSubId = 123;
+        MmsStats mmsStats = new MmsStats(mContext, mPersistMmsAtomsStorage, inactiveSubId,
+                mTelephonyManager, null, true);
+        mmsStats.addAtomToStorage(Activity.RESULT_OK);
+
+        ArgumentCaptor<IncomingMms> incomingMmsCaptor = ArgumentCaptor.forClass(IncomingMms.class);
+        verify(mPersistMmsAtomsStorage).addIncomingMms(incomingMmsCaptor.capture());
+        IncomingMms incomingMms = incomingMmsCaptor.getValue();
+        assertThat(incomingMms.getRat()).isEqualTo(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        assertThat(incomingMms.getResult()).isEqualTo(INCOMING_MMS__RESULT__MMS_RESULT_SUCCESS);
+        assertThat(incomingMms.getRoaming()).isEqualTo(ServiceState.ROAMING_TYPE_NOT_ROAMING);
+        assertThat(incomingMms.getSimSlotIndex()).isEqualTo(
+                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(incomingMms.getIsMultiSim()).isEqualTo(false);
+        assertThat(incomingMms.getIsEsim()).isEqualTo(false);
+        assertThat(incomingMms.getCarrierId()).isEqualTo(TelephonyManager.UNKNOWN_CARRIER_ID);
+        assertThat(incomingMms.getMmsCount()).isEqualTo(1);
+        assertThat(incomingMms.getRetryId()).isEqualTo(0);
+        assertThat(incomingMms.getHandledByCarrierApp()).isEqualTo(false);
+        assertThat(incomingMms.getIsManagedProfile()).isEqualTo(false);
+        verifyNoMoreInteractions(mPersistMmsAtomsStorage);
+    }
+
+    @Test
+    public void addAtomToStorage_outgoingMms_default() {
+        doReturn(null).when(mTelephonyManager).getServiceState();
+        doReturn(TelephonyManager.UNKNOWN_CARRIER_ID).when(mTelephonyManager).getSimCarrierId();
+        int inactiveSubId = 123;
+        MmsStats mmsStats = new MmsStats(mContext, mPersistMmsAtomsStorage, inactiveSubId,
+                mTelephonyManager, null, false);
+        mmsStats.addAtomToStorage(Activity.RESULT_OK);
+
+        ArgumentCaptor<OutgoingMms> outgoingMmsCaptor = ArgumentCaptor.forClass(OutgoingMms.class);
+        verify(mPersistMmsAtomsStorage).addOutgoingMms(outgoingMmsCaptor.capture());
+        OutgoingMms outgoingMms = outgoingMmsCaptor.getValue();
+        assertThat(outgoingMms.getRat()).isEqualTo(TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        assertThat(outgoingMms.getResult()).isEqualTo(OUTGOING_MMS__RESULT__MMS_RESULT_SUCCESS);
+        assertThat(outgoingMms.getRoaming()).isEqualTo(ServiceState.ROAMING_TYPE_NOT_ROAMING);
+        assertThat(outgoingMms.getSimSlotIndex()).isEqualTo(
+                SubscriptionManager.INVALID_SIM_SLOT_INDEX);
+        assertThat(outgoingMms.getIsMultiSim()).isEqualTo(false);
+        assertThat(outgoingMms.getIsEsim()).isEqualTo(false);
+        assertThat(outgoingMms.getCarrierId()).isEqualTo(TelephonyManager.UNKNOWN_CARRIER_ID);
+        assertThat(outgoingMms.getMmsCount()).isEqualTo(1);
+        assertThat(outgoingMms.getRetryId()).isEqualTo(0);
+        assertThat(outgoingMms.getHandledByCarrierApp()).isEqualTo(false);
+        assertThat(outgoingMms.getIsFromDefaultApp()).isEqualTo(false);
+        assertThat(outgoingMms.getIsManagedProfile()).isEqualTo(false);
+        verifyNoMoreInteractions(mPersistMmsAtomsStorage);
+    }
+
+    @Test
+    public void getDataRoamingType_serviceState_notNull() {
+        ServiceState serviceState = mock(ServiceState.class);
+        doReturn(serviceState).when(mTelephonyManager).getServiceState();
+        MmsStats mmsStats = new MmsStats(mContext, mPersistMmsAtomsStorage, 1,
+                mTelephonyManager, null, true);
+        mmsStats.addAtomToStorage(Activity.RESULT_OK);
+
+        ArgumentCaptor<IncomingMms> incomingMmsCaptor = ArgumentCaptor.forClass(IncomingMms.class);
+        verify(mPersistMmsAtomsStorage).addIncomingMms(incomingMmsCaptor.capture());
+        IncomingMms incomingMms = incomingMmsCaptor.getValue();
+        assertThat(incomingMms.getRoaming()).isEqualTo(ServiceState.ROAMING_TYPE_NOT_ROAMING);
+    }
+
+
+    @Test
+    public void isDefaultMmsApp_subId_inactive() {
+        int inactiveSubId = 123;
+        doReturn(false).when(mSubscriptionManager)
+                .isActiveSubscriptionId(eq(inactiveSubId));
+
+        MmsStats mmsStats = new MmsStats(mContext, mPersistMmsAtomsStorage, inactiveSubId,
+                mTelephonyManager, null, false);
+        mmsStats.addAtomToStorage(Activity.RESULT_OK);
+
+        // getSubscriptionUserHandle should not be called if subID is inactive.
+        verify(mSubscriptionManager, never()).getSubscriptionUserHandle(eq(inactiveSubId));
+    }
+}
\ No newline at end of file
diff --git a/tests/unittests/src/com/android/mms/service/metrics/PersistMmsAtomsStorageTest.java b/tests/unittests/src/com/android/mms/service/metrics/PersistMmsAtomsStorageTest.java
new file mode 100644
index 0000000..7f604bc
--- /dev/null
+++ b/tests/unittests/src/com/android/mms/service/metrics/PersistMmsAtomsStorageTest.java
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mms.service.metrics;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.telephony.ServiceState;
+import android.telephony.TelephonyManager;
+import androidx.annotation.Nullable;
+
+import com.android.mms.IncomingMms;
+import com.android.mms.OutgoingMms;
+import com.android.mms.PersistMmsAtoms;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PersistMmsAtomsStorageTest {
+    private static final String TEST_FILE = "PersistMmsAtomsStorageTest.pb";
+    @Rule
+    public TemporaryFolder mFolder = new TemporaryFolder();
+    private File mTestFile;
+    private static final long START_TIME_MILLIS = 2000L;
+    private static final int CARRIER1_ID = 1435;
+    private static final int CARRIER2_ID = 1187;
+    private TestablePersistMmsAtomsStorage mTestablePersistMmsAtomsStorage;
+    // IncomingMms
+    private List<IncomingMms> mIncomingMmsList;
+    private IncomingMms mIncomingMms1Proto;
+    private IncomingMms mIncomingMms2Proto;
+    // OutgoingMms
+    private List<OutgoingMms> mOutgoingMmsList;
+    private OutgoingMms mOutgoingMms1Proto;
+    private OutgoingMms mOutgoingMms2Proto;
+    // Mocked classes
+    private Context mContext;
+    private PackageManager mPackageManager;
+    private FileOutputStream mTestFileOutputStream;
+    // Comparator to compare proto objects
+    private static final Comparator<Object> sProtoComparator =
+            new Comparator<Object>() {
+                @Override
+                public int compare(Object o1, Object o2) {
+                    if (o1 == o2) {
+                        return 0;
+                    }
+                    if (o1 == null) {
+                        return -1;
+                    }
+                    if (o2 == null) {
+                        return 1;
+                    }
+                    assertEquals(o1.getClass(), o2.getClass());
+                    return o1.toString().compareTo(o2.toString());
+                }
+            };
+
+
+    @Before
+    public void setUp() throws Exception {
+        mTestFileOutputStream = mock(FileOutputStream.class);
+        mContext = mock(Context.class);
+        mPackageManager = mock(PackageManager.class);
+        makeTestData();
+
+        // By default, test loading with real file IO and saving with mocks.
+        mTestFile = mFolder.newFile(TEST_FILE);
+        doReturn(false).when(mPackageManager).
+                hasSystemFeature(PackageManager.FEATURE_RAM_LOW);
+        doReturn(mPackageManager).when(mContext).getPackageManager();
+        doReturn(mTestFileOutputStream).when(mContext).openFileOutput(anyString(), anyInt());
+        doReturn(mTestFile).when(mContext).getFileStreamPath(anyString());
+    }
+
+    @After
+    public void tearDown() {
+        mTestFile.delete();
+        mTestFile = null;
+        mFolder = null;
+        mIncomingMmsList = null;
+        mIncomingMms1Proto = null;
+        mIncomingMms2Proto = null;
+        mOutgoingMmsList = null;
+        mOutgoingMms1Proto = null;
+        mOutgoingMms2Proto = null;
+        mTestablePersistMmsAtomsStorage = null;
+        mTestFileOutputStream = null;
+        mPackageManager = null;
+        mContext = null;
+    }
+
+    @Test
+    public void loadAtoms_fileNotExist() {
+        mTestFile.delete();
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // No exception should be thrown, storage should be empty, pull time should be start time.
+        assertAllPullTimestampEquals(START_TIME_MILLIS);
+        assertStorageIsEmptyForAllAtoms();
+    }
+
+    @Test
+    public void loadAtoms_unreadable() throws Exception {
+        createEmptyTestFile();
+        mTestFile.setReadable(false);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // No exception should be thrown, storage should be empty, pull time should be start time.
+        assertAllPullTimestampEquals(START_TIME_MILLIS);
+        assertStorageIsEmptyForAllAtoms();
+    }
+
+    @Test
+    public void loadAtoms_emptyProto() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // No exception should be thrown, storage should be empty, pull time should be start time.
+        assertAllPullTimestampEquals(START_TIME_MILLIS);
+        assertStorageIsEmptyForAllAtoms();
+    }
+
+    @Test
+    public void loadAtoms_malformedFile() throws Exception {
+        FileOutputStream stream = new FileOutputStream(mTestFile);
+        stream.write("This is not a proto file.".getBytes(StandardCharsets.UTF_8));
+        stream.close();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // No exception should be thrown, storage should be empty, pull time should be start time.
+        assertAllPullTimestampEquals(START_TIME_MILLIS);
+        assertStorageIsEmptyForAllAtoms();
+    }
+
+    @Test
+    public void loadAtoms_pullTimeMissing() throws Exception {
+        // Create test file with lastPullTimeMillis = 0L, i.e. default/unknown.
+        createTestFile(0L);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // No exception should be thrown, storage should be match, pull time should be start time.
+        assertAllPullTimestampEquals(START_TIME_MILLIS);
+        assertProtoListEqualsIgnoringOrder(mIncomingMmsList,
+                mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+        assertProtoListEqualsIgnoringOrder(mOutgoingMmsList,
+                mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    @Test
+    public void loadAtoms_validContents() throws Exception {
+        createTestFile(100L);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+
+        // No exception should be thrown, storage and pull time should match.
+        assertAllPullTimestampEquals(100L);
+        assertProtoListEqualsIgnoringOrder(mIncomingMmsList,
+                mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+        assertProtoListEqualsIgnoringOrder(mOutgoingMmsList,
+                mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    @Test
+    public void addIncomingMms_emptyProto() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addIncomingMms(mIncomingMms1Proto);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // IncomingMms should be added successfully, there should not be any OutgoingMms,
+        // changes should be saved.
+        verifyCurrentStateSavedToFileOnce();
+        assertProtoListIsEmpty(mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+        List<IncomingMms> expectedIncomingMmsList = new ArrayList<>();
+        expectedIncomingMmsList.add(mIncomingMms1Proto);
+        assertProtoListEquals(expectedIncomingMmsList,
+                mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+    }
+
+    @Test
+    public void addIncomingMms_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addIncomingMms(mIncomingMms1Proto);
+        mTestablePersistMmsAtomsStorage.addIncomingMms(mIncomingMms2Proto);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // IncomingMms should be added successfully.
+        verifyCurrentStateSavedToFileOnce();
+        List<IncomingMms> expectedIncomingMmsList = Arrays.asList(mIncomingMms1Proto,
+                mIncomingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedIncomingMmsList,
+                mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+    }
+
+    @Test
+    public void addIncomingMms_updateExistingEntries() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        // Add copy of mIncomingMms1Proto.
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addIncomingMms(copyOf(mIncomingMms1Proto));
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // mIncomingMms1Proto's mms count should be increased by 1 and avgIntervalMillis
+        // should be updated correctly.
+        verifyCurrentStateSavedToFileOnce();
+        IncomingMms newIncomingMm1Proto = copyOf(mIncomingMms1Proto);
+        newIncomingMm1Proto = newIncomingMm1Proto.toBuilder()
+                .setMmsCount(2)
+                .setAvgIntervalMillis(mIncomingMms1Proto.getAvgIntervalMillis())
+                .build();
+        List<IncomingMms> expectedIncomingMmsList = Arrays.asList(newIncomingMm1Proto,
+                mIncomingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedIncomingMmsList,
+                mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+    }
+
+    @Test
+    public void addIncomingMms_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        // Add 26 mms whereas max size is 25.
+        IncomingMms mms = IncomingMms.newBuilder()
+                .setRoaming(ServiceState.ROAMING_TYPE_DOMESTIC)
+                .setSimSlotIndex(0)
+                .setIsMultiSim(false)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER1_ID)
+                .setMmsCount(1)
+                .setAvgIntervalMillis(500L)
+                .setRetryId(0)
+                .setHandledByCarrierApp(false)
+                .build();
+        for (int ratType = 0; ratType < 5; ratType++) {
+            for (int resultType = 0; resultType < 5; resultType++) {
+                mms = mms.toBuilder().setRat(ratType).setResult(resultType).build();
+                mTestablePersistMmsAtomsStorage.addIncomingMms(mms);
+                mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+            }
+        }
+
+        // Add 26th mms 5 times
+        IncomingMms lastMms = copyOf(mms);
+        lastMms = lastMms.toBuilder().setRat(6).setResult(6).build();
+        for (int i = 0; i < 5; i++) {
+            mTestablePersistMmsAtomsStorage.addIncomingMms(lastMms);
+            mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Last mms should be present in storage.
+        assertHasMmsAndCountAvg(mTestablePersistMmsAtomsStorage.getIncomingMms(0L),
+                lastMms, 5L, lastMms.getAvgIntervalMillis());
+    }
+
+    @Test
+    public void getIncomingMms_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        // Pull interval less than minimum.
+        mTestablePersistMmsAtomsStorage.incTimeMillis(50L);
+
+        List<IncomingMms> incomingMmsList = mTestablePersistMmsAtomsStorage
+                .getIncomingMms(100L);
+        // Should be denied.
+        assertNull(incomingMmsList);
+    }
+
+    @Test
+    public void getIncomingMms_withSavedAtoms() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        List<IncomingMms> incomingMmsList1 = mTestablePersistMmsAtomsStorage
+                .getIncomingMms(50L);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        List<IncomingMms> incomingMmsList2 = mTestablePersistMmsAtomsStorage
+                .getIncomingMms(50L);
+
+        // First set of results should be equal to file contents.
+        List<IncomingMms> expectedIncomingMmsList = Arrays.asList(mIncomingMms1Proto,
+                mIncomingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedIncomingMmsList, incomingMmsList1);
+        // Second set of results should be empty.
+        expectedIncomingMmsList = new ArrayList<>();
+        assertProtoListEqualsIgnoringOrder(expectedIncomingMmsList, incomingMmsList2);
+        // Corresponding pull timestamp should be updated and saved.
+        assertEquals(START_TIME_MILLIS + 200L, mTestablePersistMmsAtomsStorage
+                .getAtomsProto().getIncomingMmsPullTimestampMillis());
+        InOrder inOrder = inOrder(mTestFileOutputStream);
+        assertEquals(START_TIME_MILLIS + 100L,
+                getAtomsWritten(inOrder).getIncomingMmsPullTimestampMillis());
+        assertEquals(START_TIME_MILLIS + 200L,
+                getAtomsWritten(inOrder).getIncomingMmsPullTimestampMillis());
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    @Test
+    public void addOutgoingMms_emptyProto() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addOutgoingMms(mOutgoingMms1Proto);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // OutgoingMms should be added successfully, there should not be any IncomingMms,
+        // changes should be saved.
+        verifyCurrentStateSavedToFileOnce();
+        assertProtoListIsEmpty(mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+        List<OutgoingMms> expectedOutgoingMmsList = new ArrayList<>();
+        expectedOutgoingMmsList.add(mOutgoingMms1Proto);
+        assertProtoListEquals(expectedOutgoingMmsList,
+                mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    @Test
+    public void addOutgoingMms_withExistingEntries() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addOutgoingMms(mOutgoingMms1Proto);
+        mTestablePersistMmsAtomsStorage.addOutgoingMms(mOutgoingMms2Proto);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // OutgoingMms should be added successfully
+        verifyCurrentStateSavedToFileOnce();
+        List<OutgoingMms> expectedOutgoingMmsList = Arrays.asList(mOutgoingMms1Proto,
+                mOutgoingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedOutgoingMmsList,
+                mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    @Test
+    public void addOutgoingMms_updateExistingEntries() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        // Add copy of mOutgoingMms1Proto
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.addOutgoingMms(copyOf(mOutgoingMms1Proto));
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+
+        // mOutgoingMms1Proto's mms count should be increased by 1 and avgIntervalMillis
+        // should be updated correctly.
+        verifyCurrentStateSavedToFileOnce();
+        OutgoingMms newOutgoingMm1Proto = copyOf(mOutgoingMms1Proto);
+        newOutgoingMm1Proto = newOutgoingMm1Proto.toBuilder()
+                .setMmsCount(2)
+                .setAvgIntervalMillis(mOutgoingMms1Proto.getAvgIntervalMillis())
+                .build();
+        List<OutgoingMms> expectedOutgoingMmsList = Arrays.asList(newOutgoingMm1Proto,
+                mOutgoingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedOutgoingMmsList,
+                mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    @Test
+    public void addOutgoingMms_tooManyEntries() throws Exception {
+        createEmptyTestFile();
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        // Add 26 mms whereas max size is 25.
+        OutgoingMms mms = OutgoingMms.newBuilder()
+                .setRoaming(ServiceState.ROAMING_TYPE_DOMESTIC)
+                .setSimSlotIndex(0)
+                .setIsMultiSim(false)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER1_ID)
+                .setMmsCount(1)
+                .setAvgIntervalMillis(500L)
+                .setIsFromDefaultApp(true)
+                .setHandledByCarrierApp(false)
+                .setRetryId(0)
+                .build();
+        for (int ratType = 0; ratType < 5; ratType++) {
+            for (int resultType = 0; resultType < 5; resultType++) {
+                mms = mms.toBuilder().setRat(ratType).setResult(resultType).build();
+                mTestablePersistMmsAtomsStorage.addOutgoingMms(mms);
+                mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+            }
+        }
+
+        // Add 26th mms 5 times
+        OutgoingMms lastMms = copyOf(mms);
+        lastMms = lastMms.toBuilder().setRat(6).setResult(6).build();
+        for (int i = 0; i < 5; i++) {
+            mTestablePersistMmsAtomsStorage.addOutgoingMms(lastMms);
+            mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        }
+
+        // Last mms should be present in storage.
+        assertHasMmsAndCountAvg(mTestablePersistMmsAtomsStorage.getOutgoingMms(0L),
+                lastMms, 5L, lastMms.getAvgIntervalMillis());
+    }
+
+    @Test
+    public void getOutgoingMms_tooFrequent() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        // Pull interval less than minimum.
+        mTestablePersistMmsAtomsStorage.incTimeMillis(50L);
+
+        List<OutgoingMms> outgoingMmsList = mTestablePersistMmsAtomsStorage
+                .getOutgoingMms(100L);
+        // Should be denied.
+        assertNull(outgoingMmsList);
+    }
+
+    @Test
+    public void getOutgoingMms_withSavedAtoms() throws Exception {
+        createTestFile(START_TIME_MILLIS);
+
+        mTestablePersistMmsAtomsStorage = new TestablePersistMmsAtomsStorage(mContext);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        List<OutgoingMms> outgoingMmsList1 = mTestablePersistMmsAtomsStorage
+                .getOutgoingMms(50L);
+        mTestablePersistMmsAtomsStorage.incTimeMillis(100L);
+        List<OutgoingMms> outgoingMmsList2 = mTestablePersistMmsAtomsStorage
+                .getOutgoingMms(50L);
+
+        // First set of results should be equal to file contents.
+        List<OutgoingMms> expectedOutgoingMmsList = Arrays.asList(mOutgoingMms1Proto,
+                mOutgoingMms2Proto);
+        assertProtoListEqualsIgnoringOrder(expectedOutgoingMmsList, outgoingMmsList1);
+        // Second set of results should be empty.
+        expectedOutgoingMmsList = new ArrayList<>();
+        assertProtoListEqualsIgnoringOrder(expectedOutgoingMmsList, outgoingMmsList2);
+        // Corresponding pull timestamp should be updated and saved.
+        assertEquals(START_TIME_MILLIS + 200L, mTestablePersistMmsAtomsStorage
+                .getAtomsProto().getOutgoingMmsPullTimestampMillis());
+        InOrder inOrder = inOrder(mTestFileOutputStream);
+        assertEquals(START_TIME_MILLIS + 100L,
+                getAtomsWritten(inOrder).getOutgoingMmsPullTimestampMillis());
+        assertEquals(START_TIME_MILLIS + 200L,
+                getAtomsWritten(inOrder).getOutgoingMmsPullTimestampMillis());
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    /** Utilities */
+
+    private void assertAllPullTimestampEquals(long timestamp) {
+        assertEquals(timestamp, mTestablePersistMmsAtomsStorage.getAtomsProto()
+                .getIncomingMmsPullTimestampMillis());
+        assertEquals(timestamp, mTestablePersistMmsAtomsStorage.getAtomsProto()
+                .getOutgoingMmsPullTimestampMillis());
+    }
+
+    private void assertStorageIsEmptyForAllAtoms() {
+        assertProtoListIsEmpty(mTestablePersistMmsAtomsStorage.getIncomingMms(0L));
+        assertProtoListIsEmpty(mTestablePersistMmsAtomsStorage.getOutgoingMms(0L));
+    }
+
+    private static <T> void assertProtoListIsEmpty(@Nullable List<T> list) {
+        assertNotNull(list);
+        assertEquals(0, list.size());
+    }
+
+    private static <T> void assertProtoListEquals(@Nullable List<T> expected,
+            @Nullable List<T> actual) {
+        assertNotNull(expected);
+        assertNotNull(actual);
+        String message =
+                "Expected:\n" + expected.stream().map(Object::toString).collect(
+                        Collectors.joining(", "))
+                        + "\nGot:\n" + actual.stream().map(Object::toString).collect(
+                        Collectors.joining(", "));
+        assertEquals(message, expected.size(), actual.size());
+        for (int i = 0; i < expected.size(); i++) {
+            assertTrue(message, expected.get(i).equals(actual.get(i)));
+        }
+    }
+
+    private static <T> void assertProtoListEqualsIgnoringOrder(@Nullable List<T> expected,
+            @Nullable List<T> actual) {
+        assertNotNull(expected);
+        assertNotNull(actual);
+        expected = new ArrayList<>(expected);
+        actual = new ArrayList<>(actual);
+        Collections.sort(expected, sProtoComparator);
+        Collections.sort(actual, sProtoComparator);
+        assertProtoListEquals(expected, actual);
+    }
+
+    private static void assertHasMmsAndCountAvg(@Nullable List<IncomingMms> incomingMmsList,
+            @Nullable IncomingMms expectedMms, long expectedCount, long expectedAvg) {
+        assertNotNull(incomingMmsList);
+        assertNotNull(expectedMms);
+        long actualCount = -1;
+        long actualAvg = -1;
+        for (IncomingMms mms : incomingMmsList) {
+            if (mms.getRat() == expectedMms.getRat()
+                    && mms.getResult() == expectedMms.getResult()
+                    && mms.getRoaming() == expectedMms.getRoaming()
+                    && mms.getSimSlotIndex() == expectedMms.getSimSlotIndex()
+                    && mms.getIsMultiSim() == expectedMms.getIsMultiSim()
+                    && mms.getIsEsim() == expectedMms.getIsEsim()
+                    && mms.getCarrierId() == expectedMms.getCarrierId()
+                    && mms.getRetryId() == expectedMms.getRetryId()
+                    && mms.getHandledByCarrierApp() == expectedMms.getHandledByCarrierApp()) {
+                actualCount = mms.getMmsCount();
+                actualAvg = mms.getAvgIntervalMillis();
+            }
+        }
+
+        assertEquals(expectedCount, actualCount);
+        assertEquals(expectedAvg, actualAvg);
+    }
+
+    private static void assertHasMmsAndCountAvg(@Nullable List<OutgoingMms> outgoingMmsList,
+            @Nullable OutgoingMms expectedMms, long expectedCount, long expectedAvg) {
+        assertNotNull(outgoingMmsList);
+        assertNotNull(expectedMms);
+        long actualCount = -1;
+        long actualAvg = -1;
+        for (OutgoingMms mms : outgoingMmsList) {
+            if (mms.getRat() == expectedMms.getRat()
+                    && mms.getResult() == expectedMms.getResult()
+                    && mms.getRoaming() == expectedMms.getRoaming()
+                    && mms.getSimSlotIndex() == expectedMms.getSimSlotIndex()
+                    && mms.getIsMultiSim() == expectedMms.getIsMultiSim()
+                    && mms.getIsEsim() == expectedMms.getIsEsim()
+                    && mms.getCarrierId() == expectedMms.getCarrierId()
+                    && mms.getIsFromDefaultApp() == expectedMms.getIsFromDefaultApp()
+                    && mms.getRetryId() == expectedMms.getRetryId()
+                    && mms.getHandledByCarrierApp() == expectedMms.getHandledByCarrierApp()) {
+                actualCount = mms.getMmsCount();
+                actualAvg = mms.getAvgIntervalMillis();
+            }
+        }
+
+        assertEquals(expectedCount, actualCount);
+        assertEquals(expectedAvg, actualAvg);
+    }
+
+    private void verifyCurrentStateSavedToFileOnce() throws Exception {
+        InOrder inOrder = inOrder(mTestFileOutputStream);
+        inOrder.verify(mTestFileOutputStream, times(1))
+                .write(eq(mTestablePersistMmsAtomsStorage.getAtomsProto().toByteArray()));
+        inOrder.verify(mTestFileOutputStream, times(1)).close();
+        inOrder.verifyNoMoreInteractions();
+    }
+
+    private PersistMmsAtoms getAtomsWritten(@Nullable InOrder inOrder) throws Exception {
+        if (inOrder == null) {
+            inOrder = inOrder(mTestFileOutputStream);
+        }
+        ArgumentCaptor bytesCaptor = ArgumentCaptor.forClass(Object.class);
+        inOrder.verify(mTestFileOutputStream, times(1))
+                .write((byte[]) bytesCaptor.capture());
+        PersistMmsAtoms savedAtoms = PersistMmsAtoms.parseFrom((byte[]) bytesCaptor.getValue());
+        inOrder.verify(mTestFileOutputStream, times(1)).close();
+        return savedAtoms;
+    }
+
+    private static IncomingMms copyOf(IncomingMms source) {
+        return source.toBuilder().build();
+    }
+
+    private static OutgoingMms copyOf(OutgoingMms source) {
+        return source.toBuilder().build();
+    }
+
+    private void makeTestData() {
+        mIncomingMms1Proto = IncomingMms.newBuilder()
+                .setRat(TelephonyManager.NETWORK_TYPE_LTE)
+                .setResult(1)
+                .setRoaming(ServiceState.ROAMING_TYPE_NOT_ROAMING)
+                .setSimSlotIndex(0)
+                .setIsMultiSim(true)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER1_ID)
+                .setAvgIntervalMillis(500L)
+                .setMmsCount(1)
+                .setRetryId(0)
+                .setHandledByCarrierApp(false)
+                .build();
+
+        mIncomingMms2Proto = IncomingMms.newBuilder()
+                .setRat(TelephonyManager.NETWORK_TYPE_LTE)
+                .setResult(1)
+                .setRoaming(ServiceState.ROAMING_TYPE_NOT_ROAMING)
+                .setSimSlotIndex(1)
+                .setIsMultiSim(false)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER2_ID)
+                .setAvgIntervalMillis(500L)
+                .setMmsCount(1)
+                .setRetryId(0)
+                .setHandledByCarrierApp(false)
+                .build();
+
+        mIncomingMmsList = new ArrayList<>();
+        mIncomingMmsList.add(mIncomingMms1Proto);
+        mIncomingMmsList.add(mIncomingMms2Proto);
+
+        mOutgoingMms1Proto = OutgoingMms.newBuilder()
+                .setRat(0)
+                .setResult(1)
+                .setRoaming(0)
+                .setSimSlotIndex(0)
+                .setIsMultiSim(true)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER1_ID)
+                .setAvgIntervalMillis(500L)
+                .setMmsCount(1)
+                .setIsFromDefaultApp(true)
+                .setRetryId(0)
+                .setHandledByCarrierApp(false)
+                .build();
+
+        mOutgoingMms2Proto = OutgoingMms.newBuilder()
+                .setRat(0)
+                .setResult(1)
+                .setRoaming(0)
+                .setSimSlotIndex(0)
+                .setIsMultiSim(false)
+                .setIsEsim(false)
+                .setCarrierId(CARRIER2_ID)
+                .setAvgIntervalMillis(500L)
+                .setMmsCount(1)
+                .setIsFromDefaultApp(true)
+                .setRetryId(0)
+                .setHandledByCarrierApp(false)
+                .build();
+
+        mOutgoingMmsList = new ArrayList<>();
+        mOutgoingMmsList.add(mOutgoingMms1Proto);
+        mOutgoingMmsList.add(mOutgoingMms2Proto);
+    }
+
+    private void createEmptyTestFile() throws Exception {
+        PersistMmsAtoms atoms = PersistMmsAtoms.newBuilder().build();
+        FileOutputStream stream = new FileOutputStream(mTestFile);
+        stream.write(atoms.toByteArray());
+        stream.close();
+    }
+
+    private void createTestFile(long lastPullTimeMillis) throws Exception {
+        PersistMmsAtoms atoms = PersistMmsAtoms.newBuilder()
+                .setBuildFingerprint(Build.FINGERPRINT)
+                .setIncomingMmsPullTimestampMillis(lastPullTimeMillis)
+                .setOutgoingMmsPullTimestampMillis(lastPullTimeMillis)
+                .addAllIncomingMms(mIncomingMmsList)
+                .addAllOutgoingMms(mOutgoingMmsList)
+                .build();
+
+        FileOutputStream stream = new FileOutputStream(mTestFile);
+        stream.write(atoms.toByteArray());
+        stream.close();
+    }
+
+    private static class TestablePersistMmsAtomsStorage extends PersistMmsAtomsStorage {
+        private long mTimeMillis = START_TIME_MILLIS;
+
+        TestablePersistMmsAtomsStorage(Context context) {
+            super(context);
+            // Remove delay for saving to persistent storage during tests.
+            mSaveImmediately = true;
+        }
+
+        @Override
+        protected long getWallTimeMillis() {
+            // NOTE: super class constructor will be executed before private field is set, which
+            // gives the wrong start time (mTimeMillis will have its default value of 0L).
+            return mTimeMillis == 0L ? START_TIME_MILLIS : mTimeMillis;
+        }
+
+        private void incTimeMillis(long timeMillis) {
+            mTimeMillis += timeMillis;
+        }
+
+        private PersistMmsAtoms getAtomsProto() {
+            // NOTE: unlike other methods in PersistAtomsStorage, this is not synchronized, but
+            // should be fine since the test is single-threaded.
+            return mPersistMmsAtoms;
+        }
+    }
+}
\ No newline at end of file
