diff --git a/src/com/android/providers/telephony/TelephonyProvider.java b/src/com/android/providers/telephony/TelephonyProvider.java
index 1d10cf9..681c307 100644
--- a/src/com/android/providers/telephony/TelephonyProvider.java
+++ b/src/com/android/providers/telephony/TelephonyProvider.java
@@ -69,16 +69,21 @@
 import static android.provider.Telephony.Carriers.USER_VISIBLE;
 import static android.provider.Telephony.Carriers.WAIT_TIME_RETRY;
 import static android.provider.Telephony.Carriers._ID;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.app.compat.CompatChanges;
 import android.content.ComponentName;
 import android.content.ContentProvider;
+import android.content.ContentProviderOperation;
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.OperationApplicationException;
 import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.content.UriMatcher;
@@ -94,8 +99,10 @@
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.Environment;
 import android.os.IBinder;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemProperties;
@@ -103,9 +110,11 @@
 import android.provider.Telephony;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.TelephonyProtoEnums;
 import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
 import android.util.ArrayMap;
+import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
 import android.util.Xml;
@@ -113,29 +122,35 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.TelephonyStatsLog;
 import com.android.internal.util.XmlUtils;
 import android.service.carrier.IApnSourceService;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.Integer;
+import java.lang.NoSuchFieldException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 import java.util.zip.CheckedInputStream;
 import java.util.zip.CRC32;
 
@@ -178,6 +193,8 @@
     private static final int URL_FILTERED_USING_SUBID = 25;
     private static final int URL_SIM_APN_LIST_FILTERED = 26;
     private static final int URL_SIM_APN_LIST_FILTERED_ID = 27;
+    private static final int URL_SIMINFO_SUW_RESTORE = 28;
+    private static final int URL_SIMINFO_SIM_INSERTED_RESTORE = 29;
 
     /**
      * Default value for mtu if it's not set. Moved from PhoneConstants.
@@ -243,6 +260,18 @@
     private static final String ORDER_BY_SUB_ID =
             Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + " ASC";
 
+    @VisibleForTesting
+    static final String BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE = "sim_specific_settings_file";
+    // Holds names and value types of SimInfoDb columns to backup.
+    private static final Map<String, Integer> SIM_INFO_COLUMNS_TO_BACKUP = new HashMap();
+    private static final String KEY_SIMINFO_DB_ROW_PREFIX = "KEY_SIMINFO_DB_ROW_";
+    private static final int DEFAULT_INT_COLUMN_VALUE = -111;
+    private static final String SIM_INSERTED_RESTORE_URI_SUFFIX = "sim_inserted_restore";
+    @VisibleForTesting
+    static final String KEY_BACKUP_DATA_FORMAT_VERSION = "KEY_BACKUP_DATA_FORMAT_VERSION";
+    @VisibleForTesting
+    static final String KEY_PREVIOUSLY_RESTORED_SUB_IDS = "KEY_PREVIOUSLY_RESTORED_SUB_IDS";
+
     private static final int INVALID_APN_ID = -1;
     private static final List<String> CARRIERS_UNIQUE_FIELDS = new ArrayList<String>();
     private static final Set<String> CARRIERS_BOOLEAN_FIELDS = new HashSet<String>();
@@ -351,6 +380,25 @@
         MVNO_TYPE_STRING_MAP.put("imsi", ApnSetting.MVNO_TYPE_IMSI);
         MVNO_TYPE_STRING_MAP.put("gid", ApnSetting.MVNO_TYPE_GID);
         MVNO_TYPE_STRING_MAP.put("iccid", ApnSetting.MVNO_TYPE_ICCID);
+
+        // To B&R a new config, simply add the column name and its appropriate value type to
+        // SIM_INFO_COLUMNS_TO_BACKUP. To no longer B&R a column, simply remove it from
+        // SIM_INFO_COLUMNS_TO_BACKUP. For both cases, add appropriate versioning logic in
+        // convertBackedUpDataToContentValues(ContentValues contenValues)
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID, Cursor.FIELD_TYPE_INTEGER);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+                Telephony.SimInfo.COLUMN_ICC_ID, Cursor.FIELD_TYPE_STRING);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+                Telephony.SimInfo.COLUMN_NUMBER, Cursor.FIELD_TYPE_STRING);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+            Telephony.SimInfo.COLUMN_CARRIER_ID, Cursor.FIELD_TYPE_INTEGER);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+            Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED, Cursor.FIELD_TYPE_INTEGER);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+                Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED, Cursor.FIELD_TYPE_INTEGER);
+        SIM_INFO_COLUMNS_TO_BACKUP.put(
+                Telephony.SimInfo.COLUMN_VT_IMS_ENABLED, Cursor.FIELD_TYPE_INTEGER);
     }
 
     @VisibleForTesting
@@ -487,6 +535,11 @@
 
         s_urlMatcher.addURI("telephony", "siminfo", URL_SIMINFO);
         s_urlMatcher.addURI("telephony", "siminfo/#", URL_SIMINFO_USING_SUBID);
+        s_urlMatcher.addURI("telephony", "siminfo/backup_and_restore/suw_restore",
+                URL_SIMINFO_SUW_RESTORE);
+        s_urlMatcher.addURI("telephony", "siminfo/backup_and_restore/" +
+                SIM_INSERTED_RESTORE_URI_SUFFIX,
+                URL_SIMINFO_SIM_INSERTED_RESTORE);
 
         s_urlMatcher.addURI("telephony", "carriers/subId/*", URL_TELEPHONY_USING_SUBID);
         s_urlMatcher.addURI("telephony", "carriers/current/subId/*", URL_CURRENT_USING_SUBID);
@@ -2986,6 +3039,459 @@
     }
 
     @Override
+    public synchronized Bundle call(String method, @Nullable String args, @Nullable Bundle bundle) {
+        if (SubscriptionManager.GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME.equals(method)) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, TAG);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                return retrieveSimSpecificSettings();
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        } else if (SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME.equals(method)) {
+            getContext().enforceCallingOrSelfPermission(
+                    android.Manifest.permission.MODIFY_PHONE_STATE, TAG);
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                restoreSimSpecificSettings(bundle, args);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        } else {
+            loge("method is not recognized");
+        }
+
+        return null;
+    }
+
+    /**
+     * See {@link SubscriptionController#GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME} for details
+     */
+    private Bundle retrieveSimSpecificSettings() {
+        Bundle resultBundle = new Bundle();
+        resultBundle.putByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA,
+                getSimSpecificDataToBackUp());
+
+        return resultBundle;
+    }
+
+    /**
+     * Attempts to restore the backed up sim-specific configs to device. End result is SimInfoDB is
+     * modified to match any backed up configs for the appropriate inserted sims.
+     *
+     * @param bundle containing the data to be restored. If {@code null}, then backed up
+     * data should already be in internal storage and will be retrieved from there.
+     * @param iccId of the SIM that a restore is being attempted for. If {@code null}, then try to
+     * restore for all simInfo entries in SimInfoDB
+     */
+    private void restoreSimSpecificSettings(@Nullable Bundle bundle, @Nullable String iccId) {
+        int restoreCase = TelephonyProtoEnums.SIM_RESTORE_CASE_UNDEFINED_USE_CASE;
+        if (bundle != null) {
+            restoreCase = TelephonyProtoEnums.SIM_RESTORE_CASE_SUW;
+            if (!writeSimSettingsToInternalStorage(
+                    bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA))) {
+                return;
+            }
+        } else if (iccId != null){
+            restoreCase = TelephonyProtoEnums.SIM_RESTORE_CASE_SIM_INSERTED;
+        }
+        mergeBackedUpDataToSimInfoDb(restoreCase, iccId);
+    }
+
+    @VisibleForTesting
+    boolean writeSimSettingsToInternalStorage(byte[] data) {
+        File file = new File(getContext().getFilesDir(), BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE);
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            fos.write(data);
+        } catch (IOException e) {
+            loge("Not able to create internal file with per-sim configs. Failed with error "
+                    + e);
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Attempt to match any SimInfoDB entries to what is in the internal backup data file and
+     * update DB entry with the adequate backed up data.
+     *
+     * @param restoreCase one of the SimSpecificSettingsRestoreMatchingCriteria values defined in
+     * frameworks/proto_logging/stats/enums/telephony/enums.proto
+     * @param iccId of the SIM that a restore is being attempted for. If {@code null}, then try to
+     * restore for all simInfo entries in SimInfoDB
+     */
+    private void mergeBackedUpDataToSimInfoDb(int restoreCase, @Nullable String iccId) {
+        // Get data stored in internal file
+        File file = new File(getContext().getFilesDir(), BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE);
+        if (!file.exists()) {
+            loge("internal sim-specific settings backup data file does not exist. "
+                + "Aborting restore");
+            return;
+        }
+
+        PersistableBundle bundle = null;
+        try (FileInputStream fis = new FileInputStream(file)) {
+            bundle = PersistableBundle.readFromStream(fis);
+        } catch (IOException e) {
+            loge("Failed to convert backed up per-sim configs to bundle. Stopping restore. "
+                + "Failed with error " + e);
+            return;
+        }
+
+        String selection = null;
+        String[] selectionArgs = null;
+        if (iccId != null) {
+            selection = Telephony.SimInfo.COLUMN_ICC_ID + "=?";
+            selectionArgs = new String[]{iccId};
+        }
+        try (Cursor cursor = query(
+                SubscriptionManager.CONTENT_URI,
+                new String[]{
+                        Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                        Telephony.SimInfo.COLUMN_ICC_ID,
+                        Telephony.SimInfo.COLUMN_NUMBER,
+                        Telephony.SimInfo.COLUMN_CARRIER_ID},
+                selection,
+                selectionArgs,
+                ORDER_BY_SUB_ID)) {
+            findAndRestoreAllMatches(bundle, cursor, restoreCase);
+        }
+    }
+
+    private void findAndRestoreAllMatches(PersistableBundle backedUpDataBundle, Cursor cursor,
+            int restoreCase) {
+        int[] previouslyRestoredSubIdsArray =
+                backedUpDataBundle.getIntArray(KEY_PREVIOUSLY_RESTORED_SUB_IDS);
+        List<Integer> previouslyRestoredSubIdsList = previouslyRestoredSubIdsArray != null
+                ? Arrays.stream(previouslyRestoredSubIdsArray).boxed().collect(Collectors.toList())
+                : new ArrayList<>();
+        List<Integer> newlyRestoredSubIds = new ArrayList<>();
+        int backupDataFormatVersion = backedUpDataBundle
+                .getInt(KEY_BACKUP_DATA_FORMAT_VERSION, -1);
+
+        while (cursor != null && cursor.moveToNext()) {
+            // Get all the possible matching criteria.
+            int subIdColumnIndex = cursor.getColumnIndex(
+                    Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID);
+            int currSubIdFromDb = cursor.getInt(subIdColumnIndex);
+
+            if (previouslyRestoredSubIdsList.contains(currSubIdFromDb)) {
+                // Abort restore for any sims that were previously restored.
+                continue;
+            }
+
+            int iccIdColumnIndex = cursor.getColumnIndex(Telephony.SimInfo.COLUMN_ICC_ID);
+            String currIccIdFromDb = cursor.getString(iccIdColumnIndex);
+
+            int phoneNumberColumnIndex = cursor.getColumnIndex(Telephony.SimInfo.COLUMN_NUMBER);
+            String currPhoneNumberFromDb = cursor.getString(phoneNumberColumnIndex);
+
+            int carrierIdColumnIndex = cursor.getColumnIndex(Telephony.SimInfo.COLUMN_CARRIER_ID);
+            int currCarrierIdFromDb = cursor.getInt(carrierIdColumnIndex);
+
+            // Find the best match from backed up data.
+            SimRestoreMatch bestRestoreMatch = null;
+            for (int rowNum = 0; true; rowNum++) {
+                PersistableBundle currRow = backedUpDataBundle.getPersistableBundle(
+                        KEY_SIMINFO_DB_ROW_PREFIX + rowNum);
+                if (currRow == null) {
+                    break;
+                }
+
+                SimRestoreMatch currSimRestoreMatch = new SimRestoreMatch(
+                        currIccIdFromDb, currCarrierIdFromDb, currPhoneNumberFromDb, currRow,
+                        backupDataFormatVersion);
+
+                if (currSimRestoreMatch == null) {
+                    continue;
+                }
+
+                /*
+                 * The three following match cases are ordered by descending priority:
+                 *   - Match by iccId: If iccId of backup data matches iccId of any inserted sims,
+                 *       we confidently restore all configs.
+                 *   - Match phone number and carrierId: If both of these values match, we
+                 *       confidently restore all configs.
+                 *   - Match only carrierId: If only carrierId of backup data matches an inserted
+                 *       sim, we only restore non-sensitive configs.
+                 *
+                 * Having a matchScore value for each match allows us to control these priorities.
+                 */
+                if (bestRestoreMatch == null || (currSimRestoreMatch.getMatchScore()
+                        >= bestRestoreMatch.getMatchScore()
+                        && currSimRestoreMatch.getContentValues() != null)) {
+                    bestRestoreMatch = currSimRestoreMatch;
+                }
+            }
+
+            if (bestRestoreMatch != null) {
+                if (bestRestoreMatch.getMatchScore() != 0) {
+                    if (restoreCase == TelephonyProtoEnums.SIM_RESTORE_CASE_SUW) {
+                        update(SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI,
+                                bestRestoreMatch.getContentValues(),
+                                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
+                                new String[]{Integer.toString(currSubIdFromDb)});
+                    } else if (restoreCase == TelephonyProtoEnums.SIM_RESTORE_CASE_SIM_INSERTED) {
+                        Uri simInsertedRestoreUri = Uri.withAppendedPath(
+                                SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+                                SIM_INSERTED_RESTORE_URI_SUFFIX);
+                        update(simInsertedRestoreUri,
+                                bestRestoreMatch.getContentValues(),
+                                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID + "=?",
+                                new String[]{Integer.toString(currSubIdFromDb)});
+                    }
+                    log("Restore of inserterd SIM's sim-specific settings has been successfully "
+                            + "completed.");
+                    TelephonyStatsLog.write(TelephonyStatsLog.SIM_SPECIFIC_SETTINGS_RESTORED,
+                            TelephonyProtoEnums.SIM_RESTORE_RESULT_SUCCESS,
+                            restoreCase, bestRestoreMatch.getMatchingCriteriaForLogging());
+                    newlyRestoredSubIds.add(currSubIdFromDb);
+                } else {
+                    TelephonyStatsLog.write(TelephonyStatsLog.SIM_SPECIFIC_SETTINGS_RESTORED,
+                            TelephonyProtoEnums.SIM_RESTORE_RESULT_NONE_MATCH,
+                            restoreCase, bestRestoreMatch.getMatchingCriteriaForLogging());
+                }
+            } else {
+                log("No matching SIM in backup data. SIM-specific settings not restored.");
+                TelephonyStatsLog.write(TelephonyStatsLog.SIM_SPECIFIC_SETTINGS_RESTORED,
+                        TelephonyProtoEnums.SIM_RESTORE_RESULT_ZERO_SIM_IN_BACKUP,
+                        restoreCase, TelephonyProtoEnums.SIM_RESTORE_MATCHING_CRITERIA_NONE);
+            }
+        }
+
+        // Update the internal file with subIds that we just restored.
+        previouslyRestoredSubIdsList.addAll(newlyRestoredSubIds);
+        backedUpDataBundle.putIntArray(
+                KEY_PREVIOUSLY_RESTORED_SUB_IDS,
+                previouslyRestoredSubIdsList.stream().mapToInt(i -> i).toArray());
+        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+            backedUpDataBundle.writeToStream(outputStream);
+            writeSimSettingsToInternalStorage(outputStream.toByteArray());
+        } catch (IOException e) {
+            loge("Not able to convert SimInfoDB to byte array. Not storing which subIds were "
+                    + "restored");
+        }
+    }
+
+    private static class SimRestoreMatch {
+
+        private Set<Integer> matches = new ArraySet<>();
+        private int subId;
+        private ContentValues contentValues;
+        private int matchingCriteria;
+        private int matchScore;
+
+        private static final int ICCID_MATCH = 1;
+        private static final int PHONE_NUMBER_MATCH = 2;
+        private static final int CARRIER_ID_MATCH = 3;
+
+        public SimRestoreMatch(String iccIdFromDb, int carrierIdFromDb,
+                String phoneNumberFromDb, PersistableBundle backedUpSimInfoEntry,
+                int backupDataFormatVersion) {
+            subId = backedUpSimInfoEntry.getInt(
+                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                DEFAULT_INT_COLUMN_VALUE);
+            String iccIdFromBackup = backedUpSimInfoEntry.getString(Telephony.SimInfo.COLUMN_ICC_ID,
+                  "");
+            String phoneNumberFromBackup = backedUpSimInfoEntry.getString(
+                  Telephony.SimInfo.COLUMN_NUMBER, "");
+            int carrierIdFromBackup = backedUpSimInfoEntry.getInt(
+                  Telephony.SimInfo.COLUMN_CARRIER_ID,
+                  TelephonyManager.UNKNOWN_CARRIER_ID);
+
+
+            // find all matching fields
+            if (iccIdFromDb != null && iccIdFromDb.equals(iccIdFromBackup)
+                    && !iccIdFromBackup.isEmpty()) {
+                matches.add(ICCID_MATCH);
+            }
+            if (carrierIdFromDb == carrierIdFromBackup
+                    && carrierIdFromBackup != TelephonyManager.UNKNOWN_CARRIER_ID) {
+                matches.add(CARRIER_ID_MATCH);
+            }
+            if (phoneNumberFromDb != null && phoneNumberFromDb.equals(phoneNumberFromBackup)
+                    && !phoneNumberFromBackup.isEmpty()) {
+                matches.add(PHONE_NUMBER_MATCH);
+            }
+
+            contentValues = convertBackedUpDataToContentValues(
+                    backedUpSimInfoEntry, backupDataFormatVersion);
+            matchScore = calculateMatchScore();
+            matchingCriteria = calculateMatchingCriteria();
+        }
+
+        public int getSubId() {
+            return subId;
+        }
+
+        public ContentValues getContentValues() {
+            return contentValues;
+        }
+
+        public int getMatchScore() {
+            return matchScore;
+        }
+
+        private int calculateMatchScore() {
+            int score = 0;
+
+            if (matches.contains(ICCID_MATCH)) {
+                score += 100;
+            }
+            if (matches.contains(CARRIER_ID_MATCH)) {
+                if (matches.contains(PHONE_NUMBER_MATCH)) {
+                    score += 10;
+                } else {
+                    score += 1;
+                }
+            }
+
+            return score;
+        }
+
+        public int getMatchingCriteriaForLogging() {
+            return matchingCriteria;
+        }
+
+        private int calculateMatchingCriteria() {
+            if (matches.contains(ICCID_MATCH)) {
+                return TelephonyProtoEnums.SIM_RESTORE_MATCHING_CRITERIA_ICCID;
+            }
+            if (matches.contains(CARRIER_ID_MATCH)) {
+                if (matches.contains(PHONE_NUMBER_MATCH)) {
+                    return TelephonyProtoEnums
+                        .SIM_RESTORE_MATCHING_CRITERIA_CARRIER_ID_AND_PHONE_NUMBER;
+                } else {
+                    return TelephonyProtoEnums.SIM_RESTORE_MATCHING_CRITERIA_CARRIER_ID_ONLY;
+                }
+            }
+            return TelephonyProtoEnums.SIM_RESTORE_MATCHING_CRITERIA_NONE;
+        }
+
+        private ContentValues convertBackedUpDataToContentValues(
+                PersistableBundle backedUpSimInfoEntry, int backupDataFormatVersion) {
+            if (DATABASE_VERSION != 48 << 16) {
+                throw new AssertionError("The database schema has been updated which might make "
+                    + "the format of #BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE outdated. Make sure to "
+                    + "1) review whether any of the columns in #SIM_INFO_COLUMNS_TO_BACKUP have "
+                    + "been migrated or deleted, 2) add the new column name into one of those "
+                    + "maps, 3) add migration code in this method as necessary, and 4) update the "
+                    + "version check in this if statement.");
+            }
+            ContentValues contentValues = new ContentValues();
+            // Don't restore anything if restoring from a newer version of the current database.
+            if (backupDataFormatVersion > DATABASE_VERSION) {
+                return null;
+            }
+
+            /* Any migration logic should be placed under this comment block.
+             * ex:
+             *   if (backupDataFormatVersion >= 48 << 19) {
+             *     contentValues.put(NEW_COLUMN_NAME_2,
+             *         backedUpSimInfoEntry.getInt( OLD_COLUMN_NAME, DEFAULT_INT_COLUMN_VALUE));
+             *     ...
+             *   } else if (backupDataFormatVersion >= 48 << 17) {
+             *     contentValues.put(NEW_COLUMN_NAME_1,
+             *         backedUpSimInfoEntry.getInt(OLD_COLUMN_NAME, DEFAULT_INT_COLUMN_VALUE));
+             *     ...
+             *   } else {
+             *     // The values from the first format of backup ever available.
+             *     contentValues.put(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+             *         backedUpSimInfoEntry.getInt(
+             *             Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+             *             DEFAULT_INT_COLUMN_VALUE));
+             *     contentValues.put(Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+             *         backedUpSimInfoEntry.getString(
+             *              Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED, ""));
+             *     contentValues.put(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+             *               backedUpSimInfoEntry.getString(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+             *               ""));
+             *   }
+             *
+             * Also make sure to add necessary removal of sensitive settings in
+             * polishContentValues(ContentValues contentValues).
+             */
+            contentValues.put(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                    backedUpSimInfoEntry.getInt(
+                            Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                            DEFAULT_INT_COLUMN_VALUE));
+            contentValues.put(Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+                    backedUpSimInfoEntry.getInt(
+                            Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+                            DEFAULT_INT_COLUMN_VALUE));
+            contentValues.put(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+                    backedUpSimInfoEntry.getInt(
+                            Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+                            DEFAULT_INT_COLUMN_VALUE));
+
+            return polishContentValues(contentValues);
+        }
+
+        private ContentValues polishContentValues(ContentValues contentValues) {
+            if (matches.contains(ICCID_MATCH)) {
+                return contentValues;
+            } else if (matches.contains(CARRIER_ID_MATCH)) {
+                if (!matches.contains(PHONE_NUMBER_MATCH)) {
+                    // Low confidence match should not restore sensitive configs.
+                    if (contentValues.containsKey(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED)) {
+                        contentValues.remove(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED);
+                    }
+                }
+                return contentValues;
+            }
+            return null;
+        }
+
+    }
+
+    /**
+     * Retrieves data from all columns in SimInfoDB of backup/restore interest.
+     *
+     * @return data of interest from SimInfoDB as a byte array.
+     */
+    private byte[] getSimSpecificDataToBackUp() {
+        String[] projection = SIM_INFO_COLUMNS_TO_BACKUP.keySet()
+                .toArray(new String[SIM_INFO_COLUMNS_TO_BACKUP.size()]);
+
+        try (Cursor cursor = query(SubscriptionManager.CONTENT_URI, projection, null, null, null);
+                ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+            PersistableBundle topLevelBundle = new PersistableBundle();
+            topLevelBundle.putInt(KEY_BACKUP_DATA_FORMAT_VERSION, DATABASE_VERSION);
+            for (int rowNum = 0; cursor != null && cursor.moveToNext(); rowNum++) {
+                PersistableBundle rowBundle = convertSimInfoDbEntryToPersistableBundle(cursor);
+                topLevelBundle.putPersistableBundle(KEY_SIMINFO_DB_ROW_PREFIX + rowNum, rowBundle);
+            }
+            topLevelBundle.writeToStream(outputStream);
+            return outputStream.toByteArray();
+        } catch (IOException e) {
+            loge("Not able to convert SimInfoDB to byte array. Returning empty byte array");
+            return new byte[0];
+        }
+    }
+
+    private static PersistableBundle convertSimInfoDbEntryToPersistableBundle(Cursor cursor) {
+        PersistableBundle bundle = new PersistableBundle();
+        for (Map.Entry<String, Integer> column : SIM_INFO_COLUMNS_TO_BACKUP.entrySet()) {
+            String columnName = column.getKey();
+            int columnType = column.getValue();
+            int columnIndex = cursor.getColumnIndex(columnName);
+            if (columnType == Cursor.FIELD_TYPE_INTEGER) {
+                bundle.putInt(columnName, cursor.getInt(columnIndex));
+            } else if (columnType == Cursor.FIELD_TYPE_STRING) {
+                bundle.putString(columnName, cursor.getString(columnIndex));
+            } else {
+                throw new AssertionError("SimInfoDB column to be backed up is not recognized. Make "
+                    + "sure to properly add the desired colum name and value type to "
+                    + "SIM_INFO_COLUMNS_TO_BACKUP.");
+            }
+        }
+
+        return bundle;
+    }
+
+    @Override
     public synchronized Cursor query(Uri url, String[] projectionIn, String selection,
             String[] selectionArgs, String sort) {
         if (VDBG) log("query: url=" + url + ", projectionIn=" + projectionIn + ", selection="
@@ -3948,6 +4454,15 @@
                 break;
             }
 
+            case URL_SIMINFO_SUW_RESTORE:
+                count = db.update(SIMINFO_TABLE, values, where, whereArgs);
+                uriType = URL_SIMINFO_SUW_RESTORE;
+                break;
+
+            case URL_SIMINFO_SIM_INSERTED_RESTORE:
+                count = db.update(SIMINFO_TABLE, values, where, whereArgs);
+                break;
+
             default: {
                 throw new UnsupportedOperationException("Cannot update that URL: " + url);
             }
@@ -3956,6 +4471,12 @@
         if (count > 0) {
             boolean usingSubId = false;
             switch (uriType) {
+                case URL_SIMINFO_SIM_INSERTED_RESTORE:
+                    break;
+                case URL_SIMINFO_SUW_RESTORE:
+                    getContext().getContentResolver().notifyChange(
+                            SubscriptionManager.SIM_INFO_SUW_RESTORE_CONTENT_URI, null);
+                    // intentional fall through from above case
                 case URL_SIMINFO_USING_SUBID:
                     usingSubId = true;
                     // intentional fall through from above case
diff --git a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
index 203848a..46e9fd1 100644
--- a/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
+++ b/tests/src/com/android/providers/telephony/TelephonyProviderTest.java
@@ -34,6 +34,9 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.Environment;
+import android.os.Bundle;
+import android.os.PersistableBundle;
 import android.os.Process;
 import android.provider.Telephony;
 import android.provider.Telephony.Carriers;
@@ -53,6 +56,9 @@
 import org.junit.Test;
 import org.mockito.MockitoAnnotations;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.IntStream;
@@ -112,6 +118,112 @@
     private static final Uri URI_ENFORCE_MANAGED= Uri.parse("content://telephony/carriers/enforce_managed");
     private static final String ENFORCED_KEY = "enforced";
 
+
+    private static final int MATCHING_SUB_ID = 987654321;
+    private static final String MATCHING_ICCID = "MATCHING_ICCID";
+    private static final String MATCHING_PHONE_NUMBER = "MATCHING_PHONE_NUMBER";
+    private static final int MATCHING_CARRIER_ID = 123456789;
+
+    // Represents an entry in the SimInfoDb
+    private static final ContentValues TEST_SIM_INFO_VALUES = new ContentValues();
+    private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE = 999999;
+    private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE
+            = "ARBITRARY_TEST_STRING_VALUE";
+
+    private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID
+            = new ContentValues();
+    private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1 = 111111;
+    private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1
+            = "ARBITRARY_TEST_STRING_VALUE_1";
+
+    private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID
+            = new ContentValues();
+    private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2 = 222222;
+    private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2
+            = "ARBITRARY_TEST_STRING_VALUE_2";
+
+    private static final ContentValues BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID
+            = new ContentValues();
+    private static final int ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3 = 333333;
+    private static final String ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3
+            = "ARBITRARY_TEST_STRING_VALUE_3";
+
+    static {
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                MATCHING_SUB_ID);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_ICC_ID, MATCHING_ICCID);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_NUMBER, MATCHING_PHONE_NUMBER);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_CARD_ID,
+                ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_CARRIER_ID, MATCHING_CARRIER_ID);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+            ARBITRARY_SIMINFO_DB_TEST_INT_VALUE);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE);
+        TEST_SIM_INFO_VALUES.put(Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE);
+
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_ICC_ID, MATCHING_ICCID);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_NUMBER, ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_CARD_ID, ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_CARRIER_ID, ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_VT_IMS_ENABLED, ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID.put(
+                Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1);
+
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_ICC_ID, ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_NUMBER, MATCHING_PHONE_NUMBER);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_CARD_ID, ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_2);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_CARRIER_ID, MATCHING_CARRIER_ID);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_VT_IMS_ENABLED, ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID.put(
+                Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2);
+
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(
+                Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(Telephony.SimInfo.COLUMN_ICC_ID,
+                ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(Telephony.SimInfo.COLUMN_NUMBER,
+                ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE_3);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(Telephony.SimInfo.COLUMN_CARD_ID,
+                ARBITRARY_SIMINFO_DB_TEST_STRING_VALUE);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(Telephony.SimInfo.COLUMN_CARRIER_ID,
+                MATCHING_CARRIER_ID);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(
+                Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(Telephony.SimInfo.COLUMN_VT_IMS_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3);
+        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID.put(
+                Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED,
+                ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3);
+    }
+
     /**
      * This is used to give the TelephonyProviderTest a mocked context which takes a
      * TelephonyProvider and attaches it to the ContentResolver with telephony authority.
@@ -221,6 +333,20 @@
                 return PackageManager.PERMISSION_DENIED;
             }
         }
+
+        @Override
+        public void enforceCallingOrSelfPermission(String permission, String message) {
+            if (permission == android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE
+                    || permission == android.Manifest.permission.MODIFY_PHONE_STATE) {
+                return;
+            }
+            throw new SecurityException("Unavailable permission requested");
+        }
+
+        @Override
+        public File getFilesDir() {
+            return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
+        }
     }
 
     @Override
@@ -241,6 +367,13 @@
     protected void tearDown() throws Exception {
         super.tearDown();
         mTelephonyProviderTestable.closeDatabase();
+
+        // Remove the internal file created by SIM-specific settings restore
+        File file = new File(mContext.getFilesDir(),
+                mTelephonyProviderTestable.BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE);
+        if (file.exists()) {
+            file.delete();
+        }
     }
 
     /**
@@ -623,6 +756,162 @@
         assertEquals(0, cursor.getCount());
     }
 
+    @Test
+    public void testFullRestoreOnMatchingIccId() {
+        byte[] simSpecificSettingsData = getBackupData(
+                new ContentValues[]{
+                        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_ICCID,
+                        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID,
+                        BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID});
+        createInternalBackupFile(simSpecificSettingsData);
+        mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES);
+
+        mContext.getContentResolver().call(
+            SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+            SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+            MATCHING_ICCID, null);
+
+        Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+            null, null, null, null);
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+
+        // Make sure SubId didn't get overridden.
+        assertEquals(
+            (int)TEST_SIM_INFO_VALUES.getAsInteger(
+                    Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID),
+            getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID));
+        // Ensure all other values got updated.
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED));
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED));
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_1,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED));
+
+        assertRestoredSubIdIsRemembered();
+    }
+
+    @Test
+    public void testFullRestoreOnMatchingNumberAndCid() {
+        byte[] simSpecificSettingsData = getBackupData(
+                new ContentValues[]{
+                    BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_NUMBER_AND_CID,
+                    BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID});
+        createInternalBackupFile(simSpecificSettingsData);
+        mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES);
+
+        mContext.getContentResolver().call(
+            SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+            SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+            MATCHING_ICCID, null);
+
+        Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+            null, null, null, null);
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+
+        // Make sure SubId didn't get overridden.
+        assertEquals(
+            (int) TEST_SIM_INFO_VALUES.getAsInteger(
+                    Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID),
+            getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID));
+        // Ensure all other values got updated.
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED));
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED));
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_2,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED));
+
+        assertRestoredSubIdIsRemembered();
+    }
+
+    @Test
+    public void testFullRestoreOnMatchingCidOnly() {
+        byte[] simSpecificSettingsData = getBackupData(
+            new ContentValues[]{
+                BACKED_UP_SIM_INFO_VALUES_WITH_MATCHING_CID});
+        createInternalBackupFile(simSpecificSettingsData);
+        mContentResolver.insert(SubscriptionManager.CONTENT_URI, TEST_SIM_INFO_VALUES);
+
+        mContext.getContentResolver().call(
+            SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+            SubscriptionManager.RESTORE_SIM_SPECIFIC_SETTINGS_METHOD_NAME,
+            MATCHING_ICCID, null);
+
+        Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+            null, null, null, null);
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+
+        // Make sure SubId didn't get overridden.
+        assertEquals(
+            (int) TEST_SIM_INFO_VALUES.getAsInteger(
+                    Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID),
+            getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_UNIQUE_KEY_SUBSCRIPTION_ID));
+        // Ensure sensitive settings did not get updated.
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_IMS_RCS_UCE_ENABLED));
+        // Ensure all other values got updated.
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_ENHANCED_4G_MODE_ENABLED));
+        assertEquals(ARBITRARY_SIMINFO_DB_TEST_INT_VALUE_3,
+                getIntValueFromCursor(cursor, Telephony.SimInfo.COLUMN_VT_IMS_ENABLED));
+
+        assertRestoredSubIdIsRemembered();
+    }
+
+    private void assertRestoredSubIdIsRemembered() {
+        PersistableBundle bundle = getPersistableBundleFromInternalStorageFile();
+        int[] previouslyRestoredSubIds =
+                bundle.getIntArray(TelephonyProvider.KEY_PREVIOUSLY_RESTORED_SUB_IDS);
+        assertNotNull(previouslyRestoredSubIds);
+        assertEquals(MATCHING_SUB_ID, previouslyRestoredSubIds[0]);
+    }
+
+    private PersistableBundle getPersistableBundleFromInternalStorageFile() {
+        File file = new File(Environment.getExternalStoragePublicDirectory(
+                Environment.DIRECTORY_DOWNLOADS),
+                TelephonyProvider.BACKED_UP_SIM_SPECIFIC_SETTINGS_FILE);
+        try (FileInputStream fis = new FileInputStream(file)) {
+            return PersistableBundle.readFromStream(fis);
+        } catch (IOException e) {
+        }
+
+        return null;
+    }
+
+    private byte[] getBackupData(ContentValues[] contentValues) {
+        setUpMockContext(true);
+
+        int rowsAdded = mContentResolver.bulkInsert(SubscriptionManager.CONTENT_URI, contentValues);
+        assertEquals(rowsAdded, contentValues.length);
+
+        Cursor cursor = mContentResolver.query(SubscriptionManager.CONTENT_URI,
+            null, null, null, null);
+        assertEquals(cursor.getCount(), contentValues.length);
+
+        Bundle bundle =  mContext.getContentResolver().call(
+            SubscriptionManager.SIM_INFO_BACKUP_AND_RESTORE_CONTENT_URI,
+            SubscriptionManager.GET_SIM_SPECIFIC_SETTINGS_METHOD_NAME, null, null);
+        byte[] data = bundle.getByteArray(SubscriptionManager.KEY_SIM_SPECIFIC_SETTINGS_DATA);
+
+        int rowsDeleted = mContentResolver.delete(SubscriptionManager.CONTENT_URI, null, null);
+        assertEquals(rowsDeleted, contentValues.length);
+
+        return data;
+    }
+
+    private void createInternalBackupFile(byte[] data) {
+        mTelephonyProviderTestable.writeSimSettingsToInternalStorage(data);
+    }
+
+    private int getIntValueFromCursor(Cursor cursor, String columnName) {
+        int columnIndex = cursor.getColumnIndex(columnName);
+        return cursor.getInt(columnIndex);
+    }
+
     private int parseIdFromInsertedUri(Uri uri) throws NumberFormatException {
         return (uri != null) ? Integer.parseInt(uri.getLastPathSegment()) : -1;
     }
