Merge changes I6871db6c,Ia261e3b4,I1588bd4a,I1b81faf0,I9a596440, ...

* changes:
  [MEP] sort the simSlotMapping by logcal slot id
  In E+E, the user can't enable the PSIM
  [MEP] psim's logical slot index is 0
  [MEP] The condition of "null point check" is wrong
  Fix the settings crash when SimDialogActivity is null
  [MEP] The subscriptionInfo's getSimSlotIndex is logical slotId
  [MEP] the port id is wrong
  [MEP] Inserting a pSIM while user has 2 esims, showing the MEP dialog
  [MEP] Refactor SlotSidecar API for all of sim page.
  [MEP]The Esim's PhysicalSlotIndex is wrong
  Lost code for setting the list as visible
  The list does not follow the UX dialog design doc in alert dialog.
  The carrier name is wrong in the dialog
  Refine the mobile data selection UI
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
index b57ea92..36b5718 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java
@@ -20,6 +20,7 @@
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
+import android.provider.DeviceConfig;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -31,6 +32,7 @@
 import androidx.preference.SwitchPreference;
 
 import com.android.settings.R;
+import com.android.settings.core.SettingsUIDeviceConfig;
 import com.android.settingslib.bluetooth.A2dpProfile;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.LeAudioProfile;
@@ -70,6 +72,7 @@
     private List<CachedBluetoothDevice> mAllOfCachedDevices;
     private Map<String, List<CachedBluetoothDevice>> mProfileDeviceMap =
             new HashMap<String, List<CachedBluetoothDevice>>();
+    private boolean mIsLeContactSharingEnabled = false;
 
     @VisibleForTesting
     PreferenceCategory mProfilesContainer;
@@ -88,6 +91,8 @@
     protected void init(PreferenceScreen screen) {
         mProfilesContainer = (PreferenceCategory)screen.findPreference(getPreferenceKey());
         mProfilesContainer.setLayoutResource(R.layout.preference_bluetooth_profile_category);
+        mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI,
+                SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, false);
         // Call refresh here even though it will get called later in onResume, to avoid the
         // list of switches appearing to "pop" into the page.
         refresh();
@@ -119,21 +124,11 @@
     private void refreshProfilePreference(SwitchPreference profilePref,
             LocalBluetoothProfile profile) {
         BluetoothDevice device = mCachedDevice.getDevice();
-        boolean isLeAudioEnabled = false;
+        boolean isLeAudioEnabled = isLeAudioEnabled();
         if (profile instanceof A2dpProfile || HEADSET_CLIENT.equals(profile.toString())) {
-            LocalBluetoothProfile leAudio = mProfileManager.getLeAudioProfile();
-            if (leAudio != null) {
-                List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get(
-                        leAudio.toString());
-                if (leAudioDeviceList != null
-                        && leAudioDeviceList.stream()
-                        .anyMatch(item -> leAudio.isEnabled(item.getDevice()))) {
-                    isLeAudioEnabled = true;
-                }
-            }
             if (isLeAudioEnabled) {
                 // If the LeAudio profile is enabled on the LeAudio devices, then the
-                // SwitchPreferences of A2dp profile and Hfp profile are graied out.
+                // SwitchPreferences of A2dp profile and Hfp profile are grayed out.
                 profilePref.setEnabled(false);
             } else {
                 List<CachedBluetoothDevice> deviceList = mProfileDeviceMap.get(
@@ -145,12 +140,9 @@
         } else if (profile instanceof LeAudioProfile) {
             List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get(
                     profile.toString());
-            boolean isLeAudioProfileEnable =
-                    leAudioDeviceList != null && leAudioDeviceList.stream().anyMatch(
-                            item -> profile.isEnabled(item.getDevice()));
             boolean isBusy = leAudioDeviceList != null
                     && leAudioDeviceList.stream().anyMatch(item -> item.isBusy());
-            if (isLeAudioProfileEnable && !isBusy) {
+            if (isLeAudioEnabled && !isBusy) {
                 LocalBluetoothProfile a2dp = mProfileManager.getA2dpProfile();
                 LocalBluetoothProfile hfp = mProfileManager.getHfpClientProfile();
                 // If the LeAudio profile is enabled on the LeAudio devices, then the
@@ -169,6 +161,10 @@
                 }
             }
             profilePref.setEnabled(!isBusy);
+        } else if (profile instanceof PbapServerProfile
+                && isLeAudioEnabled
+                && !mIsLeContactSharingEnabled) {
+            profilePref.setEnabled(false);
         } else {
             profilePref.setEnabled(!mCachedDevice.isBusy());
         }
@@ -203,6 +199,20 @@
         }
     }
 
+    private boolean isLeAudioEnabled(){
+        LocalBluetoothProfile leAudio = mProfileManager.getLeAudioProfile();
+        if (leAudio != null) {
+            List<CachedBluetoothDevice> leAudioDeviceList = mProfileDeviceMap.get(
+                    leAudio.toString());
+            if (leAudioDeviceList != null
+                    && leAudioDeviceList.stream()
+                    .anyMatch(item -> leAudio.isEnabled(item.getDevice()))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Helper method to enable a profile for a device.
      */
diff --git a/src/com/android/settings/core/SettingsUIDeviceConfig.java b/src/com/android/settings/core/SettingsUIDeviceConfig.java
index 8c85c82..94074df 100644
--- a/src/com/android/settings/core/SettingsUIDeviceConfig.java
+++ b/src/com/android/settings/core/SettingsUIDeviceConfig.java
@@ -33,7 +33,11 @@
      * {@code true} if near by device suggestion is enabled in connected device page
      */
     public static final String BT_NEAR_BY_SUGGESTION_ENABLED = "bt_near_by_suggestion_enabled";
-
+    /**
+     * {@code true} if le audio contact sharing is enabled in BT device detail page
+     */
+    public static final String BT_LE_AUDIO_CONTACT_SHARING_ENABLED =
+            "bt_le_audio_contact_sharing_enabled";
     /**
      * {@code true} whether or not event_log for generic actions is enabled. Default is true.
      */
diff --git a/src/com/android/settings/network/TetherEnabler.java b/src/com/android/settings/network/TetherEnabler.java
index ef031f6..c83d971 100644
--- a/src/com/android/settings/network/TetherEnabler.java
+++ b/src/com/android/settings/network/TetherEnabler.java
@@ -31,6 +31,8 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
+import android.net.EthernetManager;
+import android.net.IpConfiguration;
 import android.net.TetheringManager;
 import android.net.wifi.WifiManager;
 import android.os.Handler;
@@ -40,6 +42,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.lifecycle.Lifecycle;
 import androidx.lifecycle.LifecycleObserver;
@@ -53,6 +56,7 @@
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -81,6 +85,16 @@
     private static final String TAG = "TetherEnabler";
     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
+    private final class EthernetListener implements EthernetManager.InterfaceStateListener {
+        public void onInterfaceStateChanged(@NonNull String iface, int state, int role,
+                @NonNull IpConfiguration configuration) {
+            if (state == EthernetManager.STATE_LINK_UP) {
+                mAvailableInterfaces.put(iface, configuration);
+            } else {
+                mAvailableInterfaces.remove(iface, configuration);
+            }
+        }
+    }
 
     @Retention(SOURCE)
     @IntDef(
@@ -108,7 +122,6 @@
     private final ConnectivityManager mConnectivityManager;
     private final TetheringManager mTetheringManager;
     private final UserManager mUserManager;
-    private final String mEthernetRegex;
     private final DataSaverBackend mDataSaverBackend;
     private boolean mDataSaverEnabled;
     @VisibleForTesting
@@ -121,6 +134,10 @@
     private final AtomicReference<BluetoothPan> mBluetoothPan;
     private boolean mBluetoothEnableForTether;
     private final BluetoothAdapter mBluetoothAdapter;
+    private final EthernetManager mEthernetManager;
+    private final EthernetManager.InterfaceStateListener mEthernetListener = new EthernetListener();
+    private final ConcurrentHashMap<String, IpConfiguration> mAvailableInterfaces =
+            new ConcurrentHashMap<>();
 
     public TetherEnabler(Context context, SwitchWidgetController switchWidgetController,
             AtomicReference<BluetoothPan> bluetoothPan) {
@@ -134,11 +151,10 @@
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
         mBluetoothPan = bluetoothPan;
-        mEthernetRegex =
-                context.getString(com.android.internal.R.string.config_ethernet_iface_regex);
         mDataSaverEnabled = mDataSaverBackend.isDataSaverEnabled();
         mListeners = new ArrayList<>();
         mMainThreadHandler = new Handler(Looper.getMainLooper());
+        mEthernetManager = context.getSystemService(EthernetManager.class);
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_START)
@@ -163,6 +179,10 @@
 
         mOnStartTetheringCallback = new OnStartTetheringCallback(this);
         updateState(null/*tethered*/);
+        if (mEthernetManager != null) {
+            mEthernetManager.addInterfaceStateListener(r -> mMainThreadHandler.post(r),
+                    mEthernetListener);
+        }
     }
 
     @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
@@ -173,6 +193,9 @@
         mContext.unregisterReceiver(mTetherChangeReceiver);
         mTetheringManager.unregisterTetheringEventCallback(mTetheringEventCallback);
         mTetheringEventCallback = null;
+        if (mEthernetManager != null) {
+            mEthernetManager.removeInterfaceStateListener(mEthernetListener);
+        }
     }
 
     public void addListener(OnTetherStateUpdateListener listener) {
@@ -246,7 +269,7 @@
                     tetherState |= TETHERING_USB_ON;
                 }
             }
-            if (s.matches(mEthernetRegex)) {
+            if (mAvailableInterfaces.containsKey(s)) {
                 tetherState |= TETHERING_ETHERNET_ON;
             }
         }