[automerger skipped] Merge "Import translations. DO NOT MERGE ANYWHERE" into sc-qpr1-dev am: b7107c8dda -s ours am: a4a45e3672 -s ours

am skip reason: subject contains skip directive

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/services/Telephony/+/16478305

Change-Id: I5d241e0d39377037de896209e5952958fd0716fa
diff --git a/src/com/android/phone/CallForwardEditPreference.java b/src/com/android/phone/CallForwardEditPreference.java
index db1c5b4..2cbb7c5 100644
--- a/src/com/android/phone/CallForwardEditPreference.java
+++ b/src/com/android/phone/CallForwardEditPreference.java
@@ -58,6 +58,7 @@
             CarrierXmlParser.SsEntry.SSAction.UNKNOWN;
     private int mAction;
     private HashMap<String, String> mCfInfo;
+    private long mDelayMillisAfterUssdSet = 1000;
 
     public CallForwardEditPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -490,8 +491,9 @@
                 mPhone.getCallForwardingOption(reason, mServiceClass,
                         obtainMessage(MESSAGE_GET_CF, msg.arg1, MESSAGE_SET_CF, ar.exception));
             } else {
-                mHandler.sendMessage(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
-                        msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception));
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(mHandler.MESSAGE_GET_CF_USSD,
+                        msg.arg1, MyHandler.MESSAGE_SET_CF, ar.exception),
+                        mDelayMillisAfterUssdSet);
             }
         }
 
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index e276082..8a007b6 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -65,6 +65,7 @@
 import com.android.internal.telephony.TelephonyPermissions;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
+import com.android.telephony.Rlog;
 
 import java.io.File;
 import java.io.FileDescriptor;
@@ -1064,6 +1065,7 @@
         }
 
         String fileName;
+        String iccid = null;
         if (isNoSimConfig) {
             fileName = getFilenameForNoSimConfig(packageName);
         } else {
@@ -1073,7 +1075,7 @@
                 return null;
             }
 
-            final String iccid = getIccIdForPhoneId(phoneId);
+            iccid = getIccIdForPhoneId(phoneId);
             final int cid = getSpecificCarrierIdForPhoneId(phoneId);
             if (iccid == null) {
                 loge("Cannot restore config with null iccid.");
@@ -1102,7 +1104,15 @@
         } catch (FileNotFoundException e) {
             // Missing file is normal occurrence that might occur with a new sim or when restoring
             // an override file during boot and should not be treated as an error.
-            if (file != null) logd("File not found: " + file.getPath());
+            if (file != null) {
+                if (isNoSimConfig) {
+                    logd("File not found: " + file.getPath());
+                } else {
+                    String filePath = file.getPath();
+                    filePath = getFilePathForLogging(filePath, iccid);
+                    logd("File not found : " + filePath);
+                }
+            }
         } catch (IOException e) {
             loge(e.toString());
         }
@@ -1110,6 +1120,22 @@
         return restoredBundle;
     }
 
+    /**
+     * This method will mask most part of iccid in the filepath for logging on userbuild
+     */
+    private String getFilePathForLogging(String filePath, String iccid) {
+        // If loggable then return with actual file path
+        if (Rlog.isLoggable(LOG_TAG, Log.VERBOSE)) {
+            return filePath;
+        }
+        String path = filePath;
+        int length = (iccid != null) ? iccid.length() : 0;
+        if (length > 5 && filePath != null) {
+            path = filePath.replace(iccid.substring(5), "***************");
+        }
+        return path;
+    }
+
     private PersistableBundle restoreConfigFromXml(String packageName, @NonNull String extraString,
             int phoneId) {
         return restoreConfigFromXml(packageName, extraString, phoneId, false);
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 4cd0a4d..c3968c2 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -22,6 +22,7 @@
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_IMS;
 import static com.android.internal.telephony.PhoneConstants.SUBSCRIPTION_KEY;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
 
 import android.Manifest;
 import android.Manifest.permission;
@@ -181,6 +182,7 @@
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
+import com.android.internal.telephony.metrics.RcsStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccIoResult;
@@ -5521,11 +5523,9 @@
      */
     public int setForbiddenPlmns(int subId, int appType, List<String> fplmns, String callingPackage,
             String callingFeatureId) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
-                callingFeatureId, "setForbiddenPlmns")) {
-            if (DBG) logv("no permissions for setForbiddenplmns");
-            throw new IllegalStateException("No Permissions for setForbiddenPlmns");
-        }
+        TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
+                mApp, subId, "setForbiddenPlmns");
+
         if (appType != TelephonyManager.APPTYPE_USIM && appType != TelephonyManager.APPTYPE_SIM) {
             loge("setForbiddenPlmnList(): App Type must be USIM or SIM");
             throw new IllegalArgumentException("Invalid appType: App Type must be USIM or SIM");
@@ -8343,6 +8343,16 @@
             int result = (int) sendRequest(CMD_ENABLE_VONR, enabled, subId,
                     workSource);
             if (DBG) log("setVoNrEnabled result: " + result);
+
+            if (result == TelephonyManager.ENABLE_VONR_SUCCESS) {
+                if (DBG) {
+                    log("Set VoNR settings in siminfo db; subId=" + subId + ", value:" + enabled);
+                }
+                SubscriptionManager.setSubscriptionProperty(
+                        subId, SubscriptionManager.NR_ADVANCED_CALLING_ENABLED,
+                        (enabled ? "1" : "0"));
+            }
+
             return result;
         } finally {
             Binder.restoreCallingIdentity(identity);
@@ -10436,6 +10446,9 @@
             } else {
                 configBinder.setRcsClientConfiguration(rcc);
             }
+
+            RcsStats.getInstance().onRcsClientProvisioningStats(subId,
+                    RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT);
         } catch (RemoteException e) {
             Rlog.e(LOG_TAG, "fail to setRcsClientConfiguration " + e.getMessage());
             throw new ServiceSpecificException(ImsException.CODE_ERROR_SERVICE_UNAVAILABLE,
diff --git a/src/com/android/phone/RcsProvisioningMonitor.java b/src/com/android/phone/RcsProvisioningMonitor.java
index 6d2bd6f..e819afc 100644
--- a/src/com/android/phone/RcsProvisioningMonitor.java
+++ b/src/com/android/phone/RcsProvisioningMonitor.java
@@ -16,6 +16,10 @@
 
 package com.android.phone;
 
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
+
 import android.Manifest;
 import android.app.role.OnRoleHoldersChangedListener;
 import android.app.role.RoleManager;
@@ -47,6 +51,8 @@
 import com.android.ims.FeatureUpdates;
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.metrics.RcsStats;
+import com.android.internal.telephony.metrics.RcsStats.RcsProvisioningCallback;
 import com.android.internal.telephony.util.HandlerExecutor;
 import com.android.internal.util.CollectionUtils;
 import com.android.telephony.Rlog;
@@ -100,6 +106,8 @@
     private final RoleManagerAdapter mRoleManager;
     private FeatureConnectorFactory<RcsFeatureManager> mFeatureFactory;
 
+    private RcsStats mRcsStats;
+
     private static RcsProvisioningMonitor sInstance;
 
     private final SubscriptionManager.OnSubscriptionsChangedListener mSubChangedListener =
@@ -227,6 +235,10 @@
             if (mSingleRegistrationCapability != singleRegistrationCapability) {
                 mSingleRegistrationCapability = singleRegistrationCapability;
                 notifyDma();
+
+                // update whether single registration supported.
+                mRcsStats.setEnableSingleRegistration(mSubId,
+                        mSingleRegistrationCapability == ProvisioningManager.STATUS_CAPABLE);
             }
         }
 
@@ -338,6 +350,9 @@
                     } else {
                         notifyRcsAutoConfigurationReceived();
                     }
+
+                    // check callback for metrics if not registered, register callback
+                    registerMetricsCallback();
                 } else {
                     // clear callbacks if rcs disconnected
                     clearCallbacks();
@@ -397,6 +412,18 @@
                 }
             }
         }
+
+        private void registerMetricsCallback() {
+            RcsProvisioningCallback rcsProvisioningCallback = mRcsStats.getRcsProvisioningCallback(
+                    mSubId, mSingleRegistrationCapability == ProvisioningManager.STATUS_CAPABLE);
+
+            // if not yet registered, register callback and set registered value
+            if (rcsProvisioningCallback != null && !rcsProvisioningCallback.getRegistered()) {
+                if (addRcsConfigCallback(rcsProvisioningCallback)) {
+                    rcsProvisioningCallback.setRegistered(true);
+                }
+            }
+        }
     }
 
     @VisibleForTesting
@@ -454,7 +481,7 @@
 
     @VisibleForTesting
     public RcsProvisioningMonitor(PhoneGlobals app, Looper looper, RoleManagerAdapter roleManager,
-            FeatureConnectorFactory<RcsFeatureManager> factory) {
+            FeatureConnectorFactory<RcsFeatureManager> factory, RcsStats rcsStats) {
         mPhone = app;
         mHandler = new MyHandler(looper);
         mCarrierConfigManager = mPhone.getSystemService(CarrierConfigManager.class);
@@ -465,6 +492,7 @@
         logv("DMA is " + mDmaPackageName);
         mDmaChangedListener = new DmaChangedListener();
         mFeatureFactory = factory;
+        mRcsStats = rcsStats;
         init();
     }
 
@@ -477,7 +505,8 @@
             HandlerThread handlerThread = new HandlerThread(TAG);
             handlerThread.start();
             sInstance = new RcsProvisioningMonitor(app, handlerThread.getLooper(),
-                    new RoleManagerAdapterImpl(app), RcsFeatureManager::getConnector);
+                    new RoleManagerAdapterImpl(app), RcsFeatureManager::getConnector,
+                    RcsStats.getInstance());
         }
         return sInstance;
     }
@@ -704,6 +733,10 @@
                     logv("acs not used, set cached config and notify.");
                     v.setConfig(cachedConfig);
                 }
+
+                // store RCS metrics - DMA changed event
+                mRcsStats.onRcsClientProvisioningStats(k,
+                        RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED);
             });
         }
     }
@@ -803,6 +836,14 @@
         }
         info.setConfig(isCompressed ? RcsConfig.decompressGzip(config) : config);
         updateConfigForSub(subId, config, isCompressed);
+
+        // Supporting ACS means config data comes from ACS
+        // store RCS metrics - received provisioning event
+        if (isAcsUsed(subId)) {
+            mRcsStats.onRcsAcsProvisioningStats(subId, 200,
+                    RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML,
+                    isRcsVolteSingleRegistrationEnabled(subId));
+        }
     }
 
     private void onReconfigRequest(int subId) {
@@ -814,6 +855,10 @@
             updateConfigForSub(subId, null, true);
             info.triggerRcsReconfiguration();
         }
+
+        // store RCS metrics - reconfig event
+        mRcsStats.onRcsClientProvisioningStats(subId,
+                RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION);
     }
 
     private void notifyDmaForSub(int subId, int capability) {
diff --git a/src/com/android/services/telephony/ImsConference.java b/src/com/android/services/telephony/ImsConference.java
index 7f088f7..c62b4fa 100644
--- a/src/com/android/services/telephony/ImsConference.java
+++ b/src/com/android/services/telephony/ImsConference.java
@@ -534,6 +534,10 @@
                 (properties & Connection.PROPERTY_IS_ADHOC_CONFERENCE) != 0);
         Log.i(this, "applyHostProperties: confProp=%s", conferenceProperties);
 
+        conferenceProperties = changeBitmask(conferenceProperties,
+                Connection.PROPERTY_CROSS_SIM,
+                (properties & Connection.PROPERTY_CROSS_SIM) != 0);
+
         return conferenceProperties;
     }
 
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index e637791..a392876 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -499,7 +499,8 @@
 
         IntentFilter intentFilter = new IntentFilter(
                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        registerReceiver(mTtyBroadcastReceiver, intentFilter);
+        registerReceiver(mTtyBroadcastReceiver, intentFilter,
+                android.Manifest.permission.MODIFY_PHONE_STATE, null);
     }
 
     @Override
@@ -2085,8 +2086,7 @@
             if (phone.getEmergencyNumberTracker() != null) {
                 if (phone.getEmergencyNumberTracker().isEmergencyNumber(
                         emergencyNumberAddress, true)) {
-                    if (phone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)
-                            || isAvailableForEmergencyCalls(phone)) {
+                    if (isAvailableForEmergencyCalls(phone)) {
                         // a)
                         if (phone.getPhoneId() == defaultVoicePhoneId) {
                             Log.i(this, "getPhoneForEmergencyCall, Phone Id that supports"
@@ -2209,12 +2209,6 @@
                 // Only sort if there are enough elements to do so.
                 if (phoneSlotStatus.size() > 1) {
                     Collections.sort(phoneSlotStatus, (o1, o2) -> {
-                        if (!o1.hasDialedEmergencyNumber && o2.hasDialedEmergencyNumber) {
-                            return -1;
-                        }
-                        if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
-                            return 1;
-                        }
                         // Sort by non-absent SIM.
                         if (o1.simState == TelephonyManager.SIM_STATE_ABSENT
                                 && o2.simState != TelephonyManager.SIM_STATE_ABSENT) {
@@ -2233,6 +2227,13 @@
                         if (o2.isLocked && !o1.isLocked) {
                             return 1;
                         }
+                        // Prefer slots where the number is considered emergency.
+                        if (!o1.hasDialedEmergencyNumber && o2.hasDialedEmergencyNumber) {
+                            return -1;
+                        }
+                        if (o1.hasDialedEmergencyNumber && !o2.hasDialedEmergencyNumber) {
+                            return 1;
+                        }
                         // sort by number of RadioAccessFamily Capabilities.
                         int compare = RadioAccessFamily.compare(o1.capabilities, o2.capabilities);
                         if (compare == 0) {
diff --git a/src/com/android/services/telephony/rcs/TelephonyRcsService.java b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
index e72b0ab..dfcea74 100644
--- a/src/com/android/services/telephony/rcs/TelephonyRcsService.java
+++ b/src/com/android/services/telephony/rcs/TelephonyRcsService.java
@@ -32,6 +32,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PhoneConfigurationManager;
+import com.android.internal.telephony.metrics.RcsStats;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.phone.ImsStateCallbackController;
 import com.android.phone.R;
@@ -164,6 +165,7 @@
         mFeatureControllers = new SparseArray<>(numSlots);
         mSlotToAssociatedSubIds = new SparseArray<>(numSlots);
         mRcsUceEnabled = sResourceProxy.getDeviceUceEnabled(mContext);
+        RcsStats.getInstance().registerUceCallback();
     }
 
     @VisibleForTesting
@@ -174,6 +176,7 @@
         mSlotToAssociatedSubIds = new SparseArray<>(numSlots);
         sResourceProxy = resourceProxy;
         mRcsUceEnabled = sResourceProxy.getDeviceUceEnabled(mContext);
+        RcsStats.getInstance().registerUceCallback();
     }
 
     /**
diff --git a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
index 8e5e073..8873402 100644
--- a/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
+++ b/tests/src/com/android/phone/RcsProvisioningMonitorTest.java
@@ -16,6 +16,10 @@
 
 package com.android.phone;
 
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED;
+import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
@@ -64,6 +68,7 @@
 import com.android.ims.FeatureConnector;
 import com.android.ims.RcsFeatureManager;
 import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.metrics.RcsStats;
 
 import org.junit.After;
 import org.junit.Before;
@@ -179,6 +184,10 @@
     private IRcsConfigCallback mCallback;
     @Mock
     private PackageManager mPackageManager;
+    @Mock
+    private RcsStats mRcsStats;
+    @Mock
+    private RcsStats.RcsProvisioningCallback mRcsProvisioningCallback;
 
     private Executor mExecutor = new Executor() {
         @Override
@@ -768,6 +777,66 @@
         assertNull(mRcsProvisioningMonitor.getImsFeatureValidationOverride(FAKE_SUB_ID_BASE));
     }
 
+    @Test
+    @SmallTest
+    public void testMetricsAcsNotUsed() throws Exception {
+        createMonitor(1);
+
+        // Not used ACS
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, false);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
+        processAllMessages();
+        verify(mRcsStats, never()).onRcsAcsProvisioningStats(anyInt(), anyInt(),
+                anyInt(), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testMetricsAcsUsed() throws Exception {
+        when(mRcsStats.getRcsProvisioningCallback(anyInt(), anyBoolean()))
+                .thenReturn(mRcsProvisioningCallback);
+        createMonitor(1);
+
+        verify(mIImsConfig, times(1))
+                .notifyRcsAutoConfigurationReceived(any(), anyBoolean());
+        // verify RcsStats.getRcsProvisioningCallback() is called
+        verify(mRcsStats, times(1)).getRcsProvisioningCallback(
+                eq(FAKE_SUB_ID_BASE), anyBoolean());
+        // verify registered callback obj which comes from RcsStats.getRcsProvisioningCallback()
+        verify(mIImsConfig, times(1))
+                .addRcsConfigCallback(eq(mRcsProvisioningCallback));
+
+        // Config data received and ACS used
+        int errorCode = 200;
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ACS_FOR_RCS_BOOL, true);
+        broadcastCarrierConfigChange(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        mRcsProvisioningMonitor.updateConfig(FAKE_SUB_ID_BASE, CONFIG_DEFAULT.getBytes(), false);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsAcsProvisioningStats(eq(FAKE_SUB_ID_BASE), eq(errorCode),
+                eq(RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML), anyBoolean());
+    }
+
+    @Test
+    @SmallTest
+    public void testMetricsClientProvisioningStats() throws Exception {
+        createMonitor(1);
+
+        // reconfig trigger
+        mRcsProvisioningMonitor.requestReconfig(FAKE_SUB_ID_BASE);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
+                eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION));
+
+        // DMA changed
+        updateDefaultMessageApplication(DEFAULT_MESSAGING_APP2);
+        processAllMessages();
+        verify(mRcsStats, times(1)).onRcsClientProvisioningStats(eq(FAKE_SUB_ID_BASE),
+                eq(RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED));
+    }
+
     private void createMonitor(int subCount) throws Exception {
         if (Looper.myLooper() == null) {
             Looper.prepare();
@@ -777,7 +846,7 @@
                 .thenReturn(mFeatureConnector);
         when(mFeatureManager.getConfig()).thenReturn(mIImsConfig);
         mRcsProvisioningMonitor = new RcsProvisioningMonitor(mPhone, mHandlerThread.getLooper(),
-                mRoleManager, mFeatureFactory);
+                mRoleManager, mFeatureFactory, mRcsStats);
         mHandler = mRcsProvisioningMonitor.getHandler();
         try {
             mLooper = new TestableLooper(mHandler.getLooper());