Merge "Link PlatformProperties statically"
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d264bad..9b029ab 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -469,6 +469,21 @@
             </intent-filter>
         </activity>
 
+        <!--
+            Handler for EuiccManager's public action intents. These are public and do not require
+            any special permissions to start, although the calling package name should be
+            whitelisted by the underlying eUICC service implementation (i.e. the LPA).
+        -->
+        <activity android:name=".euicc.EuiccPublicActionUiDispatcherActivity"
+            android:theme="@android:style/Theme.NoDisplay">
+            <!-- Max out priority to ensure nobody else will handle these intents. -->
+            <intent-filter android:priority="1000">
+                <action android:name=
+                    "android.telephony.euicc.action.START_EUICC_ACTIVATION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="EmergencyCallbackModeExitDialog"
             android:excludeFromRecents="true"
             android:label="@string/ecm_exit_dialog"
diff --git a/src/com/android/phone/CallNotifier.java b/src/com/android/phone/CallNotifier.java
index dab04f0..9e7bb39 100644
--- a/src/com/android/phone/CallNotifier.java
+++ b/src/com/android/phone/CallNotifier.java
@@ -558,7 +558,8 @@
 
     public void updatePhoneStateListeners(boolean isRefresh, int updateType, int subIdToUpdate) {
         List<SubscriptionInfo> subInfos = SubscriptionController.getInstance()
-                .getActiveSubscriptionInfoList(mApplication.getOpPackageName());
+                .getActiveSubscriptionInfoList(mApplication.getOpPackageName(),
+                        mApplication.getFeatureId());
 
         // Sort sub id list based on slot id, so that CFI/MWI notifications will be updated for
         // slot 0 first then slot 1. This is needed to ensure that when CFI or MWI is enabled for
diff --git a/src/com/android/phone/CarrierConfigLoader.java b/src/com/android/phone/CarrierConfigLoader.java
index 1d074bc..4bf4204 100644
--- a/src/com/android/phone/CarrierConfigLoader.java
+++ b/src/com/android/phone/CarrierConfigLoader.java
@@ -946,8 +946,14 @@
 
     @Override
     public @NonNull PersistableBundle getConfigForSubId(int subId, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mContext, subId, callingPackage, "getCarrierConfig")) {
+        return getConfigForSubIdWithFeature(subId, callingPackage, null);
+    }
+
+    @Override
+    public @NonNull PersistableBundle getConfigForSubIdWithFeature(int subId, String callingPackage,
+            String callingFeatureId) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mContext, subId, callingPackage,
+                callingFeatureId, "getCarrierConfig")) {
             return new PersistableBundle();
         }
 
diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 90f408b..812fabc 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -369,6 +369,10 @@
             // register for MMI/USSD
             mCM.registerForMmiComplete(mHandler, MMI_COMPLETE, null);
 
+            // Initialize cell status using current airplane mode.
+            handleAirplaneModeChange(this, Settings.Global.getInt(getContentResolver(),
+                    Settings.Global.AIRPLANE_MODE_ON, AIRPLANE_OFF));
+
             // Register for misc other intent broadcasts.
             IntentFilter intentFilter =
                     new IntentFilter(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -443,7 +447,7 @@
     }
 
     public PersistableBundle getCarrierConfigForSubId(int subId) {
-        return configLoader.getConfigForSubId(subId, getOpPackageName());
+        return configLoader.getConfigForSubIdWithFeature(subId, getOpPackageName(), getFeatureId());
     }
 
     private void registerSettingsObserver() {
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 919c964..3e1b6a5 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -1668,15 +1668,30 @@
         }
     }
 
+    @Deprecated
     @Override
     public boolean isRadioOn(String callingPackage) {
-        return isRadioOnForSubscriber(getDefaultSubscription(), callingPackage);
+        return isRadioOnWithFeature(callingPackage, null);
+    }
+
+
+    @Override
+    public boolean isRadioOnWithFeature(String callingPackage, String callingFeatureId) {
+        return isRadioOnForSubscriberWithFeature(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
+    }
+
+    @Deprecated
+    @Override
+    public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
+        return isRadioOnForSubscriberWithFeature(subId, callingPackage, null);
     }
 
     @Override
-    public boolean isRadioOnForSubscriber(int subId, String callingPackage) {
+    public boolean isRadioOnForSubscriberWithFeature(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isRadioOnForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId, "isRadioOnForSubscriber")) {
             return false;
         }
 
@@ -1998,11 +2013,12 @@
     }
 
     @Override
-    public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage) {
+    public String getNetworkCountryIsoForPhone(int phoneId, String callingPackage,
+            String callingFeatureId) {
         if (!TextUtils.isEmpty(callingPackage)) {
             final int subId = mSubscriptionController.getSubIdUsingPhoneId(phoneId);
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mApp, subId, callingPackage, "getNetworkCountryIsoForPhone")) {
+            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, subId, callingPackage,
+                    callingFeatureId, "getNetworkCountryIsoForPhone")) {
                 return "";
             }
         }
@@ -2019,7 +2035,8 @@
             // Todo: fix this when we can get the actual cellular network info when the device
             // is on IWLAN.
             if (TelephonyManager.NETWORK_TYPE_IWLAN
-                    == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName())) {
+                    == getVoiceNetworkTypeForSubscriber(subId, mApp.getPackageName(),
+                    mApp.getFeatureId())) {
                 return "";
             }
             Phone phone = PhoneFactory.getPhone(phoneId);
@@ -2250,14 +2267,14 @@
     }
 
     @Override
-    public String getImeiForSlot(int slotIndex, String callingPackage) {
+    public String getImeiForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getImeiForSlot")) {
+                callingPackage, callingFeatureId, "getImeiForSlot")) {
             return null;
         }
 
@@ -2281,7 +2298,7 @@
     }
 
     @Override
-    public String getMeidForSlot(int slotIndex, String callingPackage) {
+    public String getMeidForSlot(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
@@ -2289,7 +2306,7 @@
 
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getMeidForSlot")) {
+                callingPackage, callingFeatureId, "getMeidForSlot")) {
             return null;
         }
 
@@ -2313,14 +2330,16 @@
     }
 
     @Override
-    public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage) {
+    public String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage,
+            String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDeviceSoftwareVersionForSlot")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDeviceSoftwareVersionForSlot")) {
             return null;
         }
 
@@ -2465,14 +2484,17 @@
      * Returns the CDMA ERI icon index to display
      */
     @Override
-    public int getCdmaEriIconIndex(String callingPackage) {
-        return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getCdmaEriIconIndex(String callingPackage, String callingFeatureId) {
+        return getCdmaEriIconIndexForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage) {
+    public int getCdmaEriIconIndexForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconIndexForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconIndexForSubscriber")) {
             return -1;
         }
 
@@ -2495,14 +2517,17 @@
      * 1 - FLASHING
      */
     @Override
-    public int getCdmaEriIconMode(String callingPackage) {
-        return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getCdmaEriIconMode(String callingPackage, String callingFeatureId) {
+        return getCdmaEriIconModeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage) {
+    public int getCdmaEriIconModeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconModeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconModeForSubscriber")) {
             return -1;
         }
 
@@ -2523,14 +2548,17 @@
      * Returns the CDMA ERI text,
      */
     @Override
-    public String getCdmaEriText(String callingPackage) {
-        return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage);
+    public String getCdmaEriText(String callingPackage, String callingFeatureId) {
+        return getCdmaEriTextForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public String getCdmaEriTextForSubscriber(int subId, String callingPackage) {
+    public String getCdmaEriTextForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getCdmaEriIconTextForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getCdmaEriIconTextForSubscriber")) {
             return null;
         }
 
@@ -2665,10 +2693,12 @@
     }
 
     @Override
-    public String getVisualVoicemailPackageName(String callingPackage, int subId) {
+    public String getVisualVoicemailPackageName(String callingPackage, String callingFeatureId,
+            int subId) {
         mAppOps.checkPackage(Binder.getCallingUid(), callingPackage);
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getVisualVoicemailPackageName")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getVisualVoicemailPackageName")) {
             return null;
         }
 
@@ -2831,9 +2861,11 @@
      * Returns the unread count of voicemails for a subId
      */
     @Override
-    public int getVoiceMessageCountForSubscriber(int subId, String callingPackage) {
+    public int getVoiceMessageCountForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getVoiceMessageCountForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getVoiceMessageCountForSubscriber")) {
             return 0;
         }
         final long identity = Binder.clearCallingIdentity();
@@ -3743,13 +3775,15 @@
      * Returns the data network type for a subId; does not throw SecurityException.
      */
     @Override
-    public int getNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         final int targetSdk = getTargetSdk(callingPackage);
         if (targetSdk > android.os.Build.VERSION_CODES.Q) {
-            return getDataNetworkTypeForSubscriber(subId, callingPackage);
+            return getDataNetworkTypeForSubscriber(subId, callingPackage, callingFeatureId);
         } else if (targetSdk == android.os.Build.VERSION_CODES.Q
                 && !TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
-                        mApp, subId, callingPackage, "getNetworkTypeForSubscriber")) {
+                        mApp, subId, callingPackage, callingFeatureId,
+                "getNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3770,17 +3804,20 @@
      * Returns the data network type
      */
     @Override
-    public int getDataNetworkType(String callingPackage) {
-        return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getDataNetworkType(String callingPackage, String callingFeatureId) {
+        return getDataNetworkTypeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     /**
      * Returns the data network type for a subId
      */
     @Override
-    public int getDataNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getDataNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3801,9 +3838,11 @@
      * Returns the Voice network type for a subId
      */
     @Override
-    public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage) {
+    public int getVoiceNetworkTypeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getDataNetworkTypeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getDataNetworkTypeForSubscriber")) {
             return TelephonyManager.NETWORK_TYPE_UNKNOWN;
         }
 
@@ -3857,14 +3896,17 @@
      * or {@link Phone#LTE_ON_CDMA_TRUE}
      */
     @Override
-    public int getLteOnCdmaMode(String callingPackage) {
-        return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage);
+    public int getLteOnCdmaMode(String callingPackage, String callingFeatureId) {
+        return getLteOnCdmaModeForSubscriber(getDefaultSubscription(), callingPackage,
+                callingFeatureId);
     }
 
     @Override
-    public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage) {
+    public int getLteOnCdmaModeForSubscriber(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getLteOnCdmaModeForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getLteOnCdmaModeForSubscriber")) {
             return PhoneConstants.LTE_ON_CDMA_UNKNOWN;
         }
 
@@ -4188,9 +4230,10 @@
      * Get the forbidden PLMN List from the given app type (ex APPTYPE_USIM)
      * on a particular subscription
      */
-    public String[] getForbiddenPlmns(int subId, int appType, String callingPackage) {
+    public String[] getForbiddenPlmns(int subId, int appType, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getForbiddenPlmns")) {
+                mApp, subId, callingPackage, callingFeatureId, "getForbiddenPlmns")) {
             return null;
         }
 
@@ -4222,12 +4265,13 @@
      * @param appType the uicc app type, must be USIM or SIM.
      * @param fplmns the Forbiden plmns list that needed to be written to the SIM.
      * @param callingPackage the op Package name.
+     * @param callingFeatureId the feature in the package.
      * @return number of fplmns that is successfully written to the SIM.
      */
-    public int setForbiddenPlmns(
-            int subId, int appType, List<String> fplmns, String callingPackage) {
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "setForbiddenPlmns")) {
+    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");
         }
@@ -4403,10 +4447,11 @@
         return false;
     }
 
-    public String[] getPcscfAddress(String apnType, String callingPackage) {
+    public String[] getPcscfAddress(String apnType, String callingPackage,
+            String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, defaultPhone.getSubId(), callingPackage, "getPcscfAddress")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+                callingPackage, callingFeatureId, "getPcscfAddress")) {
             return new String[0];
         }
 
@@ -4836,10 +4881,10 @@
      * @return the preferred network type, defined in RILConstants.java.
      */
     @Override
-    public int getCalculatedPreferredNetworkType(String callingPackage) {
+    public int getCalculatedPreferredNetworkType(String callingPackage, String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
-                callingPackage, "getCalculatedPreferredNetworkType")) {
+                callingPackage, callingFeatureId, "getCalculatedPreferredNetworkType")) {
             return RILConstants.PREFERRED_NETWORK_MODE;
         }
 
@@ -5288,10 +5333,11 @@
     }
 
     @Override
-    public String getLine1NumberForDisplay(int subId, String callingPackage) {
+    public String getLine1NumberForDisplay(int subId, String callingPackage,
+            String callingFeatureId) {
         // This is open to apps with WRITE_SMS.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber(
-                mApp, subId, callingPackage, "getLine1NumberForDisplay")) {
+                mApp, subId, callingPackage, callingFeatureId, "getLine1NumberForDisplay")) {
             if (DBG_MERGE) log("getLine1NumberForDisplay returning null due to permission");
             return null;
         }
@@ -5315,9 +5361,10 @@
     }
 
     @Override
-    public String getLine1AlphaTagForDisplay(int subId, String callingPackage) {
+    public String getLine1AlphaTagForDisplay(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getLine1AlphaTagForDisplay")) {
+                mApp, subId, callingPackage, callingFeatureId, "getLine1AlphaTagForDisplay")) {
             return null;
         }
 
@@ -5335,12 +5382,13 @@
     }
 
     @Override
-    public String[] getMergedSubscriberIds(int subId, String callingPackage) {
+    public String[] getMergedSubscriberIds(int subId, String callingPackage,
+            String callingFeatureId) {
         // This API isn't public, so no need to provide a valid subscription ID - we're not worried
         // about carrier-privileged callers not having access.
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
                 mApp, SubscriptionManager.INVALID_SUBSCRIPTION_ID, callingPackage,
-                "getMergedSubscriberIds")) {
+                callingFeatureId, "getMergedSubscriberIds")) {
             return null;
         }
 
@@ -5445,7 +5493,8 @@
             // Get all subscriberIds from the group.
             final List<String> mergedSubscriberIds = new ArrayList<>();
             final List<SubscriptionInfo> groupInfos = SubscriptionController.getInstance()
-                    .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName());
+                    .getSubscriptionsInGroup(groupUuid, mApp.getOpPackageName(),
+                            mApp.getFeatureId());
             for (SubscriptionInfo subInfo : groupInfos) {
                 subscriberId = telephonyManager.getSubscriberId(subInfo.getSubscriptionId());
                 if (subscriberId != null) {
@@ -5569,10 +5618,10 @@
     }
 
     @Override
-    public boolean isVideoCallingEnabled(String callingPackage) {
+    public boolean isVideoCallingEnabled(String callingPackage, String callingFeatureId) {
         final Phone defaultPhone = getDefaultPhone();
-        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, defaultPhone.getSubId(), callingPackage, "isVideoCallingEnabled")) {
+        if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, defaultPhone.getSubId(),
+                callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5593,9 +5642,11 @@
     }
 
     @Override
-    public boolean canChangeDtmfToneLength(int subId, String callingPackage) {
+    public boolean canChangeDtmfToneLength(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5611,9 +5662,9 @@
     }
 
     @Override
-    public boolean isWorldPhone(int subId, String callingPackage) {
+    public boolean isWorldPhone(int subId, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "isVideoCallingEnabled")) {
+                mApp, subId, callingPackage, callingFeatureId, "isVideoCallingEnabled")) {
             return false;
         }
 
@@ -5688,6 +5739,12 @@
         }
     }
 
+    @Deprecated
+    @Override
+    public String getDeviceId(String callingPackage) {
+        return getDeviceIdWithFeature(callingPackage, null);
+    }
+
     /**
      * Returns the unique device ID of phone, for example, the IMEI for
      * GSM and the MEID for CDMA phones. Return null if device ID is not available.
@@ -5696,14 +5753,14 @@
      *   {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
      */
     @Override
-    public String getDeviceId(String callingPackage) {
+    public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) {
         final Phone phone = PhoneFactory.getPhone(0);
         if (phone == null) {
             return null;
         }
         int subId = phone.getSubId();
         if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mApp, subId,
-                callingPackage, "getDeviceId")) {
+                callingPackage, callingFeatureId, "getDeviceId")) {
             return null;
         }
 
@@ -5742,9 +5799,9 @@
 
     @Override
     public int getSubIdForPhoneAccountHandle(
-            PhoneAccountHandle phoneAccountHandle, String callingPackage) {
+            PhoneAccountHandle phoneAccountHandle, String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, getDefaultSubscription(),
-                callingPackage, "getSubIdForPhoneAccountHandle")) {
+                callingPackage, callingFeatureId, "getSubIdForPhoneAccountHandle")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -5871,7 +5928,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             final SubscriptionInfo info = mSubscriptionController.getActiveSubscriptionInfo(subId,
-                    phone.getContext().getOpPackageName());
+                    phone.getContext().getOpPackageName(), phone.getContext().getFeatureId());
             if (info == null) {
                 log("getSimLocaleForSubscriber, inactive subId: " + subId);
                 return null;
@@ -5909,14 +5966,16 @@
     }
 
     private List<SubscriptionInfo> getAllSubscriptionInfoList() {
-        return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName());
+        return mSubscriptionController.getAllSubInfoList(mApp.getOpPackageName(),
+                mApp.getFeatureId());
     }
 
     /**
      * NOTE: this method assumes permission checks are done and caller identity has been cleared.
      */
     private List<SubscriptionInfo> getActiveSubscriptionInfoListPrivileged() {
-        return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName());
+        return mSubscriptionController.getActiveSubscriptionInfoList(mApp.getOpPackageName(),
+                mApp.getFeatureId());
     }
 
     private final ModemActivityInfo mLastModemActivityInfo =
@@ -6002,7 +6061,7 @@
     public ServiceState getServiceStateForSubscriber(int subId, String callingPackage,
             String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getServiceStateForSubscriber")) {
+                mApp, subId, callingPackage, callingFeatureId, "getServiceStateForSubscriber")) {
             return null;
         }
 
@@ -6552,9 +6611,10 @@
      * @hide
      */
     @Override
-    public List<ClientRequestStats> getClientRequestStats(String callingPackage, int subId) {
+    public List<ClientRequestStats> getClientRequestStats(String callingPackage,
+            String callingFeatureId, int subId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getClientRequestStats")) {
+                mApp, subId, callingPackage, callingFeatureId, "getClientRequestStats")) {
             return null;
         }
         Phone phone = getPhone(subId);
@@ -6665,14 +6725,15 @@
      * Get the current modem radio state for the given slot.
      * @param slotIndex slot index.
      * @param callingPackage the name of the package making the call.
+     * @param callingFeatureId The feature in the package.
      * @return the current radio power state from the modem
      */
     @Override
-    public int getRadioPowerState(int slotIndex, String callingPackage) {
+    public int getRadioPowerState(int slotIndex, String callingPackage, String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone != null) {
-            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                    mApp, phone.getSubId(), callingPackage, "getRadioPowerState")) {
+            if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp, phone.getSubId(),
+                    callingPackage, callingFeatureId, "getRadioPowerState")) {
                 return TelephonyManager.RADIO_POWER_UNAVAILABLE;
             }
 
@@ -7021,9 +7082,11 @@
     }
 
     @Override
-    public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage) {
+    public int getNumberOfModemsWithSimultaneousDataConnections(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "getNumberOfModemsWithSimultaneousDataConnections")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "getNumberOfModemsWithSimultaneousDataConnections")) {
             return -1;
         }
 
@@ -7076,9 +7139,10 @@
 
     @Override
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
-            String callingPackage) {
+            String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, getDefaultSubscription(), callingPackage, "getEmergencyNumberList")) {
+                mApp, getDefaultSubscription(), callingPackage, callingFeatureId,
+                "getEmergencyNumberList")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
         final long identity = Binder.clearCallingIdentity();
@@ -7213,12 +7277,14 @@
      * Whether a modem stack is enabled or not.
      */
     @Override
-    public boolean isModemEnabledForSlot(int slotIndex, String callingPackage) {
+    public boolean isModemEnabledForSlot(int slotIndex, String callingPackage,
+            String callingFeatureId) {
         Phone phone = PhoneFactory.getPhone(slotIndex);
         if (phone == null) return false;
 
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, phone.getSubId(), callingPackage, "isModemEnabledForSlot")) {
+                mApp, phone.getSubId(), callingPackage, callingFeatureId,
+                "isModemEnabledForSlot")) {
             throw new SecurityException("Requires READ_PHONE_STATE permission.");
         }
 
@@ -7250,9 +7316,10 @@
 
     @Override
     @TelephonyManager.IsMultiSimSupportedResult
-    public int isMultiSimSupported(String callingPackage) {
+    public int isMultiSimSupported(String callingPackage, String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(mApp,
-                getDefaultPhone().getSubId(), callingPackage, "isMultiSimSupported")) {
+                getDefaultPhone().getSubId(), callingPackage, callingFeatureId,
+                "isMultiSimSupported")) {
             return TelephonyManager.MULTISIM_NOT_SUPPORTED_BY_HARDWARE;
         }
 
@@ -7353,9 +7420,11 @@
      * Return value defaults to true.
      */
     @Override
-    public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage) {
+    public boolean doesSwitchMultiSimConfigTriggerReboot(int subId, String callingPackage,
+            String callingFeatureId) {
         if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(
-                mApp, subId, callingPackage, "doesSwitchMultiSimConfigTriggerReboot")) {
+                mApp, subId, callingPackage, callingFeatureId,
+                "doesSwitchMultiSimConfigTriggerReboot")) {
             return false;
         }
         final long identity = Binder.clearCallingIdentity();
diff --git a/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java b/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java
new file mode 100644
index 0000000..64a40b9
--- /dev/null
+++ b/src/com/android/phone/euicc/EuiccPublicActionUiDispatcherActivity.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2019 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.phone.euicc;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.service.euicc.EuiccService;
+import android.telephony.euicc.EuiccManager;
+import android.util.Log;
+
+/**
+ * Trampoline activity to forward public eUICC intents to the active UI implementation.
+ *
+ * <p>Unlike {@link EuiccUiDispatcherActivity}, this activity does not require any permissions to
+ * start.
+ */
+public class EuiccPublicActionUiDispatcherActivity extends EuiccUiDispatcherActivity {
+    private static final String TAG = "EuiccPublicActionUiDispatcherActivity";
+
+    @Override
+    @Nullable
+    protected Intent getEuiccUiIntent() {
+        String action = getIntent().getAction();
+
+        Intent intent = new Intent();
+        // Propagate the extras from the original Intent.
+        intent.putExtras(getIntent());
+        switch (action) {
+            case EuiccManager.ACTION_START_EUICC_ACTIVATION:
+                intent.setAction(EuiccService.ACTION_START_EUICC_ACTIVATION);
+                break;
+            default:
+                Log.w(TAG, "Unsupported action: " + action);
+                return null;
+        }
+
+        return intent;
+    }
+}
diff --git a/src/com/android/services/telephony/TelecomAccountRegistry.java b/src/com/android/services/telephony/TelecomAccountRegistry.java
index 730bee5..5a1e6a6 100644
--- a/src/com/android/services/telephony/TelecomAccountRegistry.java
+++ b/src/com/android/services/telephony/TelecomAccountRegistry.java
@@ -287,7 +287,7 @@
                 mIsRttCapable = false;
             }
 
-            mIsVideoCapable = mPhone.isVideoEnabled() && !mIsRttCapable;
+            mIsVideoCapable = mPhone.isVideoEnabled();
             boolean isVideoEnabledByPlatform = ImsManager.getInstance(mPhone.getContext(),
                     mPhone.getPhoneId()).isVtEnabledByPlatform();
 
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 2d96c6b..0cff160 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -648,7 +648,8 @@
             // TODO: Switch out the underlying connection instead of creating a new
             // one and causing UI Jank.
             boolean noActiveSimCard = SubscriptionController.getInstance()
-                    .getActiveSubInfoCount(phone.getContext().getOpPackageName()) == 0;
+                    .getActiveSubInfoCount(phone.getContext().getOpPackageName(),
+                            phone.getContext().getFeatureId()) == 0;
             // If there's no active sim card and the device is in emergency mode, use E account.
             addExistingConnection(PhoneUtils.makePstnPhoneAccountHandleWithPrefix(
                     phone, "", isEmergencyNumber && noActiveSimCard), repConnection);
@@ -814,7 +815,7 @@
 
         final TelephonyConnection connection =
                 createConnectionFor(phone, null, true /* isOutgoing */, request.getAccountHandle(),
-                        request.getTelecomCallId(), request.getAddress(), request.getVideoState());
+                        request.getTelecomCallId());
         if (connection == null) {
             return Connection.createFailedConnection(
                     DisconnectCauseUtil.toTelecomDisconnectCause(
@@ -873,15 +874,9 @@
             return Connection.createCanceledConnection();
         }
 
-        // We should rely on the originalConnection to get the video state.  The request coming
-        // from Telecom does not know the video state of the incoming call.
-        int videoState = originalConnection != null ? originalConnection.getVideoState() :
-                VideoProfile.STATE_AUDIO_ONLY;
-
         TelephonyConnection connection =
                 createConnectionFor(phone, originalConnection, false /* isOutgoing */,
-                        request.getAccountHandle(), request.getTelecomCallId(),
-                        request.getAddress(), videoState);
+                        request.getAccountHandle(), request.getTelecomCallId());
         handleIncomingRtt(request, originalConnection);
         if (connection == null) {
             return Connection.createCanceledConnection();
@@ -938,6 +933,61 @@
     }
 
     @Override
+    public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        Log.i(this, "onCreateIncomingConnectionFailed, request: " + request);
+        // If there is an incoming emergency CDMA Call (while the phone is in ECBM w/ No SIM),
+        // make sure the PhoneAccount lookup retrieves the default Emergency Phone.
+        PhoneAccountHandle accountHandle = request.getAccountHandle();
+        boolean isEmergency = false;
+        if (accountHandle != null && PhoneUtils.EMERGENCY_ACCOUNT_HANDLE_ID.equals(
+                accountHandle.getId())) {
+            Log.w(this, "onCreateIncomingConnectionFailed:Emergency call failed... ");
+            isEmergency = true;
+        }
+        Phone phone = getPhoneForAccount(accountHandle, isEmergency,
+                /* Note: when not an emergency, handle can be null for unknown callers */
+                request.getAddress() == null ? null : request.getAddress().getSchemeSpecificPart());
+        if (phone == null) {
+            Log.w(this, "onCreateIncomingConnectionFailed: can not find corresponding phone.");
+            return;
+        }
+
+        Call call = phone.getRingingCall();
+        if (!call.getState().isRinging()) {
+            Log.w(this, "onCreateIncomingConnectionFailed, no ringing call found for failed call");
+            return;
+        }
+
+        com.android.internal.telephony.Connection originalConnection =
+                call.getState() == Call.State.WAITING
+                        ? call.getLatestConnection() : call.getEarliestConnection();
+        TelephonyConnection knownConnection =
+                getConnectionForOriginalConnection(originalConnection);
+        if (knownConnection != null) {
+            Log.w(this, "onCreateIncomingConnectionFailed, original connection already registered."
+                    + " Hanging it up.");
+            knownConnection.onAbort();
+            return;
+        }
+
+        TelephonyConnection connection =
+                createConnectionFor(phone, originalConnection, false /* isOutgoing */,
+                        request.getAccountHandle(), request.getTelecomCallId());
+        if (connection == null) {
+            Log.w(this, "onCreateIncomingConnectionFailed, TelephonyConnection created as null, "
+                    + "ignoring.");
+            return;
+        }
+
+        // We have to do all of this work because in some cases, hanging up the call maps to
+        // different underlying signaling (CDMA), which is already encapsulated in
+        // TelephonyConnection.
+        connection.onReject();
+        connection.close();
+    }
+
+    @Override
     public void triggerConferenceRecalculate() {
         if (mTelephonyConferenceController.shouldRecalculate()) {
             mTelephonyConferenceController.recalculate();
@@ -1036,8 +1086,8 @@
         TelephonyConnection connection =
                 createConnectionFor(phone, unknownConnection,
                         !unknownConnection.isIncoming() /* isOutgoing */,
-                        request.getAccountHandle(), request.getTelecomCallId(),
-                        request.getAddress(), videoState);
+                        request.getAccountHandle(), request.getTelecomCallId()
+                );
 
         if (connection == null) {
             return Connection.createCanceledConnection();
@@ -1311,9 +1361,7 @@
             com.android.internal.telephony.Connection originalConnection,
             boolean isOutgoing,
             PhoneAccountHandle phoneAccountHandle,
-            String telecomCallId,
-            Uri address,
-            int videoState) {
+            String telecomCallId) {
         TelephonyConnection returnConnection = null;
         int phoneType = phone.getPhoneType();
         if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
@@ -1342,15 +1390,20 @@
 
     private boolean isOriginalConnectionKnown(
             com.android.internal.telephony.Connection originalConnection) {
+        return (getConnectionForOriginalConnection(originalConnection) != null);
+    }
+
+    private TelephonyConnection getConnectionForOriginalConnection(
+            com.android.internal.telephony.Connection originalConnection) {
         for (Connection connection : getAllConnections()) {
             if (connection instanceof TelephonyConnection) {
                 TelephonyConnection telephonyConnection = (TelephonyConnection) connection;
                 if (telephonyConnection.getOriginalConnection() == originalConnection) {
-                    return true;
+                    return telephonyConnection;
                 }
             }
         }
-        return false;
+        return null;
     }
 
     /**