Merge "InternetPreferenceController V2 (7/7)" into main
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
index b0994d1..24b8f20 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingNamePreferenceController.java
@@ -18,6 +18,7 @@
 
 import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.isBroadcasting;
 
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothLeBroadcast;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.content.Context;
@@ -32,11 +33,13 @@
 
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ValidatedEditTextPreference;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.util.concurrent.Executor;
@@ -116,6 +119,8 @@
     @Nullable private AudioSharingNamePreference mPreference;
     private final Executor mExecutor;
     private final AudioSharingNameTextValidator mAudioSharingNameTextValidator;
+
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
 
     public AudioSharingNamePreferenceController(Context context, String preferenceKey) {
@@ -126,6 +131,7 @@
                 (mProfileManager != null) ? mProfileManager.getLeAudioBroadcastProfile() : null;
         mAudioSharingNameTextValidator = new AudioSharingNameTextValidator();
         mExecutor = Executors.newSingleThreadExecutor();
+        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
     }
 
     @Override
@@ -214,14 +220,19 @@
                 ThreadUtils.postOnBackgroundThread(
                         () -> {
                             if (mBroadcast != null) {
+                                boolean isBroadcasting = isBroadcasting(mBtManager);
                                 mBroadcast.setBroadcastName((String) newValue);
                                 // We currently don't have a UI field for program info so we keep it
                                 // consistent with broadcast name.
                                 mBroadcast.setProgramInfo((String) newValue);
-                                if (isBroadcasting(mBtManager)) {
+                                if (isBroadcasting) {
                                     mBroadcast.updateBroadcast();
                                 }
                                 updateBroadcastName();
+                                mMetricsFeatureProvider.action(
+                                        mContext,
+                                        SettingsEnums.ACTION_AUDIO_STREAM_NAME_UPDATED,
+                                        isBroadcasting ? 1 : 0);
                             }
                         });
         return true;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
index 7c58c43..258cf3b 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingPasswordPreferenceController.java
@@ -18,6 +18,7 @@
 
 import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.isBroadcasting;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.util.Log;
@@ -29,9 +30,11 @@
 import com.android.settings.R;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ValidatedEditTextPreference;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
 import java.nio.charset.StandardCharsets;
@@ -48,6 +51,7 @@
     @Nullable private final LocalBluetoothLeBroadcast mBroadcast;
     @Nullable private AudioSharingPasswordPreference mPreference;
     private final AudioSharingPasswordValidator mAudioSharingPasswordValidator;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
 
     public AudioSharingPasswordPreferenceController(Context context, String preferenceKey) {
         super(context, preferenceKey);
@@ -57,6 +61,7 @@
                         ? mBtManager.getProfileManager().getLeAudioBroadcastProfile()
                         : null;
         mAudioSharingPasswordValidator = new AudioSharingPasswordValidator();
+        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
     }
 
     @Override
@@ -94,18 +99,38 @@
         }
         mPreference.setEditable(!isBroadcasting(mBtManager));
         var password = mBroadcast.getBroadcastCode();
-        mPreference.setChecked(password == null || password.length == 0);
+        mPreference.setChecked(isPublicBroadcast(password));
     }
 
     @Override
     public void onPreferenceDataChanged(@NonNull String password, boolean isPublicBroadcast) {
-        if (mBroadcast == null || isBroadcasting(mBtManager)) {
-            Log.w(TAG, "onPreferenceDataChanged() changing password when broadcasting or null!");
-            return;
-        }
-        persistDefaultPassword(mContext, password);
-        mBroadcast.setBroadcastCode(isPublicBroadcast ? new byte[0] : password.getBytes());
-        updatePreference();
+        var unused =
+                ThreadUtils.postOnBackgroundThread(
+                        () -> {
+                            if (mBroadcast == null || isBroadcasting(mBtManager)) {
+                                Log.w(
+                                        TAG,
+                                        "onPreferenceDataChanged() changing password when"
+                                                + " broadcasting or null!");
+                                return;
+                            }
+                            boolean isCurrentPublicBroadcast =
+                                    isPublicBroadcast(mBroadcast.getBroadcastCode());
+                            String currentDefaultPassword = getDefaultPassword(mContext);
+                            if (password.equals(currentDefaultPassword)
+                                    && isCurrentPublicBroadcast == isPublicBroadcast) {
+                                Log.d(TAG, "onPreferenceDataChanged() nothing changed");
+                                return;
+                            }
+                            persistDefaultPassword(mContext, password);
+                            mBroadcast.setBroadcastCode(
+                                    isPublicBroadcast ? new byte[0] : password.getBytes());
+                            updatePreference();
+                            mMetricsFeatureProvider.action(
+                                    mContext,
+                                    SettingsEnums.ACTION_AUDIO_STREAM_PASSWORD_UPDATED,
+                                    isPublicBroadcast ? 1 : 0);
+                        });
     }
 
     private void updatePreference() {
@@ -116,7 +141,7 @@
                 ThreadUtils.postOnBackgroundThread(
                         () -> {
                             byte[] password = mBroadcast.getBroadcastCode();
-                            boolean noPassword = (password == null || password.length == 0);
+                            boolean noPassword = isPublicBroadcast(password);
                             String passwordToDisplay =
                                     noPassword
                                             ? getDefaultPassword(mContext)
@@ -140,25 +165,20 @@
     }
 
     private static void persistDefaultPassword(Context context, String defaultPassword) {
-        var unused =
-                ThreadUtils.postOnBackgroundThread(
-                        () -> {
-                            if (getDefaultPassword(context).equals(defaultPassword)) {
-                                return;
-                            }
+        if (getDefaultPassword(context).equals(defaultPassword)) {
+            return;
+        }
 
-                            SharedPreferences sharedPref =
-                                    context.getSharedPreferences(
-                                            SHARED_PREF_NAME, Context.MODE_PRIVATE);
-                            if (sharedPref == null) {
-                                Log.w(TAG, "persistDefaultPassword(): sharedPref is empty!");
-                                return;
-                            }
+        SharedPreferences sharedPref =
+                context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
+        if (sharedPref == null) {
+            Log.w(TAG, "persistDefaultPassword(): sharedPref is empty!");
+            return;
+        }
 
-                            SharedPreferences.Editor editor = sharedPref.edit();
-                            editor.putString(SHARED_PREF_KEY, defaultPassword);
-                            editor.apply();
-                        });
+        SharedPreferences.Editor editor = sharedPref.edit();
+        editor.putString(SHARED_PREF_KEY, defaultPassword);
+        editor.apply();
     }
 
     private static String getDefaultPassword(Context context) {
@@ -175,4 +195,8 @@
         }
         return value;
     }
+
+    private static boolean isPublicBroadcast(@Nullable byte[] password) {
+        return password == null || password.length == 0;
+    }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceBadCodeState.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceBadCodeState.java
index 1993377..56b1b2e 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceBadCodeState.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceBadCodeState.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
+import android.app.settings.SettingsEnums;
+
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
@@ -38,6 +40,17 @@
     }
 
     @Override
+    void performAction(
+            AudioStreamPreference preference,
+            AudioStreamsProgressCategoryController controller,
+            AudioStreamsHelper helper) {
+        mMetricsFeatureProvider.action(
+                preference.getContext(),
+                SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_BAD_CODE,
+                preference.getSourceOriginForLogging().ordinal());
+    }
+
+    @Override
     int getSummary() {
         return AUDIO_STREAM_ADD_SOURCE_BAD_CODE_STATE_SUMMARY;
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceFailedState.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceFailedState.java
index 5d151ee..df41c14 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceFailedState.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceFailedState.java
@@ -16,6 +16,8 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
+import android.app.settings.SettingsEnums;
+
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
@@ -38,6 +40,17 @@
     }
 
     @Override
+    void performAction(
+            AudioStreamPreference preference,
+            AudioStreamsProgressCategoryController controller,
+            AudioStreamsHelper helper) {
+        mMetricsFeatureProvider.action(
+                preference.getContext(),
+                SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER,
+                preference.getSourceOriginForLogging().ordinal());
+    }
+
+    @Override
     int getSummary() {
         return AUDIO_STREAM_ADD_SOURCE_FAILED_STATE_SUMMARY;
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseState.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseState.java
index d314d3f..00342b1 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseState.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseState.java
@@ -17,6 +17,7 @@
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
 import android.app.AlertDialog;
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 
 import androidx.annotation.Nullable;
@@ -52,6 +53,10 @@
         var metadata = preference.getAudioStreamMetadata();
         if (metadata != null) {
             helper.addSource(metadata);
+            mMetricsFeatureProvider.action(
+                    preference.getContext(),
+                    SettingsEnums.ACTION_AUDIO_STREAM_JOIN,
+                    preference.getSourceOriginForLogging().ordinal());
             // Cache the metadata that used for add source, if source is added successfully, we
             // will save it persistently.
             mAudioStreamsRepository.cacheMetadata(metadata);
@@ -66,6 +71,10 @@
                                 && preference.getAudioStreamState() == getStateEnum()) {
                             controller.handleSourceFailedToConnect(
                                     preference.getAudioStreamBroadcastId());
+                            mMetricsFeatureProvider.action(
+                                    preference.getContext(),
+                                    SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_TIMEOUT,
+                                    preference.getSourceOriginForLogging().ordinal());
                             ThreadUtils.postOnMainThread(
                                     () -> {
                                         if (controller.getFragment() != null) {
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java
index ea5abdf..2661072 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothLeBroadcastAssistant;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
@@ -33,7 +34,9 @@
 import com.android.settings.R;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 import com.android.settingslib.widget.ActionButtonsPreference;
 
@@ -44,6 +47,7 @@
         implements DefaultLifecycleObserver {
     private static final String TAG = "AudioStreamButtonController";
     private static final String KEY = "audio_stream_button";
+    private static final int SOURCE_ORIGIN_REPOSITORY = SourceOriginForLogging.REPOSITORY.ordinal();
     private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
             new AudioStreamsBroadcastAssistantCallback() {
                 @Override
@@ -56,6 +60,8 @@
                 public void onSourceRemoveFailed(BluetoothDevice sink, int sourceId, int reason) {
                     super.onSourceRemoveFailed(sink, sourceId, reason);
                     updateButton();
+                    mMetricsFeatureProvider.action(
+                            mContext, SettingsEnums.ACTION_AUDIO_STREAM_LEAVE_FAILED);
                 }
 
                 @Override
@@ -66,6 +72,10 @@
                     super.onReceiveStateChanged(sink, sourceId, state);
                     if (AudioStreamsHelper.isConnected(state)) {
                         updateButton();
+                        mMetricsFeatureProvider.action(
+                                mContext,
+                                SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED,
+                                SOURCE_ORIGIN_REPOSITORY);
                     }
                 }
 
@@ -74,6 +84,10 @@
                         BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) {
                     super.onSourceAddFailed(sink, source, reason);
                     updateButton();
+                    mMetricsFeatureProvider.action(
+                            mContext,
+                            SettingsEnums.ACTION_AUDIO_STREAM_JOIN_FAILED_OTHER,
+                            SOURCE_ORIGIN_REPOSITORY);
                 }
 
                 @Override
@@ -88,6 +102,7 @@
     private final Executor mExecutor;
     private final AudioStreamsHelper mAudioStreamsHelper;
     private final @Nullable LocalBluetoothLeBroadcastAssistant mLeBroadcastAssistant;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private @Nullable ActionButtonsPreference mPreference;
     private int mBroadcastId = -1;
 
@@ -96,6 +111,7 @@
         mExecutor = Executors.newSingleThreadExecutor();
         mAudioStreamsHelper = new AudioStreamsHelper(Utils.getLocalBtManager(context));
         mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant();
+        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
     }
 
     @Override
@@ -124,59 +140,77 @@
     }
 
     private void updateButton() {
-        if (mPreference != null) {
-            if (mAudioStreamsHelper.getAllConnectedSources().stream()
-                    .map(BluetoothLeBroadcastReceiveState::getBroadcastId)
-                    .anyMatch(connectedBroadcastId -> connectedBroadcastId == mBroadcastId)) {
-                ThreadUtils.postOnMainThread(
-                        () -> {
-                            if (mPreference != null) {
-                                mPreference.setButton1Enabled(true);
-                                mPreference
-                                        .setButton1Text(R.string.audio_streams_disconnect)
-                                        .setButton1Icon(
-                                                com.android.settings.R.drawable.ic_settings_close)
-                                        .setButton1OnClickListener(
-                                                unused -> {
+        if (mPreference == null) {
+            Log.w(TAG, "updateButton(): preference is null!");
+            return;
+        }
+        boolean isConnected =
+                mAudioStreamsHelper.getAllConnectedSources().stream()
+                        .map(BluetoothLeBroadcastReceiveState::getBroadcastId)
+                        .anyMatch(connectedBroadcastId -> connectedBroadcastId == mBroadcastId);
+
+        View.OnClickListener onClickListener;
+
+        if (isConnected) {
+            onClickListener =
+                    unused ->
+                            ThreadUtils.postOnBackgroundThread(
+                                    () -> {
+                                        mAudioStreamsHelper.removeSource(mBroadcastId);
+                                        mMetricsFeatureProvider.action(
+                                                mContext,
+                                                SettingsEnums
+                                                        .ACTION_AUDIO_STREAM_LEAVE_BUTTON_CLICK);
+                                        ThreadUtils.postOnMainThread(
+                                                () -> {
                                                     if (mPreference != null) {
                                                         mPreference.setButton1Enabled(false);
                                                     }
-                                                    mAudioStreamsHelper.removeSource(mBroadcastId);
                                                 });
-                            }
-                        });
-            } else {
-                View.OnClickListener clickToRejoin =
-                        unused ->
-                                ThreadUtils.postOnBackgroundThread(
-                                        () -> {
-                                            var metadata =
-                                                    mAudioStreamsRepository.getSavedMetadata(
-                                                            mContext, mBroadcastId);
-                                            if (metadata != null) {
-                                                mAudioStreamsHelper.addSource(metadata);
-                                                ThreadUtils.postOnMainThread(
-                                                        () -> {
-                                                            if (mPreference != null) {
-                                                                mPreference.setButton1Enabled(
-                                                                        false);
-                                                            }
-                                                        });
-                                            }
-                                        });
-                ThreadUtils.postOnMainThread(
-                        () -> {
-                            if (mPreference != null) {
-                                mPreference.setButton1Enabled(true);
-                                mPreference
-                                        .setButton1Text(R.string.audio_streams_connect)
-                                        .setButton1Icon(com.android.settings.R.drawable.ic_add_24dp)
-                                        .setButton1OnClickListener(clickToRejoin);
-                            }
-                        });
-            }
+                                    });
+            ThreadUtils.postOnMainThread(
+                    () -> {
+                        if (mPreference != null) {
+                            mPreference.setButton1Enabled(true);
+                            mPreference
+                                    .setButton1Text(R.string.audio_streams_disconnect)
+                                    .setButton1Icon(
+                                            com.android.settings.R.drawable.ic_settings_close)
+                                    .setButton1OnClickListener(onClickListener);
+                        }
+                    });
         } else {
-            Log.w(TAG, "updateButton(): preference is null!");
+            onClickListener =
+                    unused ->
+                            ThreadUtils.postOnBackgroundThread(
+                                    () -> {
+                                        var metadata =
+                                                mAudioStreamsRepository.getSavedMetadata(
+                                                        mContext, mBroadcastId);
+                                        if (metadata != null) {
+                                            mAudioStreamsHelper.addSource(metadata);
+                                            mMetricsFeatureProvider.action(
+                                                    mContext,
+                                                    SettingsEnums.ACTION_AUDIO_STREAM_JOIN,
+                                                    SOURCE_ORIGIN_REPOSITORY);
+                                            ThreadUtils.postOnMainThread(
+                                                    () -> {
+                                                        if (mPreference != null) {
+                                                            mPreference.setButton1Enabled(false);
+                                                        }
+                                                    });
+                                        }
+                                    });
+            ThreadUtils.postOnMainThread(
+                    () -> {
+                        if (mPreference != null) {
+                            mPreference.setButton1Enabled(true);
+                            mPreference
+                                    .setButton1Text(R.string.audio_streams_connect)
+                                    .setButton1Icon(com.android.settings.R.drawable.ic_add_24dp)
+                                    .setButton1OnClickListener(onClickListener);
+                        }
+                    });
         }
     }
 
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java
index 1f71b73..aeab789 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamDetailsFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.os.Bundle;
 
@@ -45,8 +46,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(chelseahao): update metrics id
-        return 0;
+        return SettingsEnums.AUDIO_STREAM_DETAIL;
     }
 
     @Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
index ea5eede..275b811 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamMediaService.java
@@ -20,6 +20,7 @@
 import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.Service;
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
@@ -40,12 +41,14 @@
 import com.android.settings.R;
 import com.android.settings.bluetooth.Utils;
 import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
 import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
 import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
 import com.android.settingslib.bluetooth.LocalBluetoothManager;
 import com.android.settingslib.bluetooth.VolumeControlProfile;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 
 import java.util.ArrayList;
 import java.util.concurrent.ExecutorService;
@@ -177,6 +180,8 @@
                             LEAVE_BROADCAST_TEXT,
                             com.android.settings.R.drawable.ic_clear);
 
+    private final MetricsFeatureProvider mMetricsFeatureProvider =
+            FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
     private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
     private int mBroadcastId;
     @Nullable private ArrayList<BluetoothDevice> mDevices;
@@ -322,6 +327,11 @@
                                         + 0);
                         if (mVolumeControl != null) {
                             mVolumeControl.setDeviceVolume(mDevices.get(0), 0, true);
+                            mMetricsFeatureProvider.action(
+                                    getApplicationContext(),
+                                    SettingsEnums
+                                            .ACTION_AUDIO_STREAM_NOTIFICATION_MUTE_BUTTON_CLICK,
+                                    1);
                         }
                     }
 
@@ -341,6 +351,10 @@
                             mVolumeControl.setDeviceVolume(
                                     mDevices.get(0), mLatestPositiveVolume, true);
                         }
+                        mMetricsFeatureProvider.action(
+                                getApplicationContext(),
+                                SettingsEnums.ACTION_AUDIO_STREAM_NOTIFICATION_MUTE_BUTTON_CLICK,
+                                0);
                     }
 
                     @Override
@@ -348,6 +362,10 @@
                         Log.d(TAG, "onCustomAction: " + action);
                         if (action.equals(LEAVE_BROADCAST_ACTION) && mAudioStreamsHelper != null) {
                             mAudioStreamsHelper.removeSource(mBroadcastId);
+                            mMetricsFeatureProvider.action(
+                                    getApplicationContext(),
+                                    SettingsEnums
+                                            .ACTION_AUDIO_STREAM_NOTIFICATION_LEAVE_BUTTON_CLICK);
                         }
                     }
                 });
@@ -379,7 +397,7 @@
                                 mLocalSession != null ? mLocalSession.getSessionToken() : null);
         if (deviceName != null && !deviceName.isEmpty()) {
             mediaStyle.setRemotePlaybackInfo(
-                    deviceName, com.android.internal.R.drawable.ic_bt_headset_hfp, null);
+                    deviceName, com.android.settingslib.R.drawable.ic_bt_le_audio, null);
         }
         Notification.Builder notificationBuilder =
                 new Notification.Builder(this, CHANNEL_ID)
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java
index f605e4b..071cf57 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreference.java
@@ -107,6 +107,12 @@
                 : AudioStreamsProgressCategoryController.AudioStreamState.UNKNOWN;
     }
 
+    SourceOriginForLogging getSourceOriginForLogging() {
+        return mAudioStream != null
+                ? mAudioStream.getSourceOriginForLogging()
+                : SourceOriginForLogging.UNKNOWN;
+    }
+
     @Override
     protected boolean shouldHideSecondTarget() {
         return mIsConnected || !mIsEncrypted;
@@ -130,11 +136,13 @@
     }
 
     static AudioStreamPreference fromMetadata(
-            Context context, BluetoothLeBroadcastMetadata source) {
+            Context context,
+            BluetoothLeBroadcastMetadata source,
+            SourceOriginForLogging sourceOriginForLogging) {
         AudioStreamPreference preference = new AudioStreamPreference(context, /* attrs= */ null);
         preference.setIsEncrypted(source.isEncrypted());
         preference.setTitle(AudioStreamsHelper.getBroadcastName(source));
-        preference.setAudioStream(new AudioStream(source));
+        preference.setAudioStream(new AudioStream(source, sourceOriginForLogging));
         return preference;
     }
 
@@ -158,11 +166,15 @@
         private static final int UNAVAILABLE = -1;
         @Nullable private BluetoothLeBroadcastMetadata mMetadata;
         @Nullable private BluetoothLeBroadcastReceiveState mReceiveState;
+        private SourceOriginForLogging mSourceOriginForLogging = SourceOriginForLogging.UNKNOWN;
         private AudioStreamsProgressCategoryController.AudioStreamState mState =
                 AudioStreamsProgressCategoryController.AudioStreamState.UNKNOWN;
 
-        private AudioStream(BluetoothLeBroadcastMetadata metadata) {
+        private AudioStream(
+                BluetoothLeBroadcastMetadata metadata,
+                SourceOriginForLogging sourceOriginForLogging) {
             mMetadata = metadata;
+            mSourceOriginForLogging = sourceOriginForLogging;
         }
 
         private AudioStream(BluetoothLeBroadcastReceiveState receiveState) {
@@ -191,6 +203,10 @@
             return mState;
         }
 
+        private SourceOriginForLogging getSourceOriginForLogging() {
+            return mSourceOriginForLogging;
+        }
+
         @Nullable
         private BluetoothLeBroadcastMetadata getMetadata() {
             return mMetadata;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java
index df176be..b0c5b6b 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java
@@ -25,7 +25,9 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.preference.Preference;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.bluetooth.BluetoothUtils;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.utils.ThreadUtils;
 
 class AudioStreamStateHandler {
@@ -35,6 +37,8 @@
 
     final AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance();
     final Handler mHandler = new Handler(Looper.getMainLooper());
+    final MetricsFeatureProvider mMetricsFeatureProvider =
+            FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
 
     AudioStreamStateHandler() {}
 
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
index f79c597..d643b89 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsDashboardFragment.java
@@ -19,6 +19,7 @@
 import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsScanQrCodeController.REQUEST_SCAN_BT_BROADCAST_QR_CODE;
 
 import android.app.Activity;
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.content.Context;
 import android.content.Intent;
@@ -32,8 +33,6 @@
 import com.android.settingslib.bluetooth.BluetoothLeBroadcastMetadataExt;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 
-import com.google.common.base.Strings;
-
 public class AudioStreamsDashboardFragment extends DashboardFragment {
     public static final String KEY_BROADCAST_METADATA = "key_broadcast_metadata";
     private static final String TAG = "AudioStreamsDashboardFrag";
@@ -46,8 +45,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO: update category id.
-        return 0;
+        return SettingsEnums.AUDIO_STREAM_MAIN;
     }
 
     @Override
@@ -78,16 +76,17 @@
         mAudioStreamsProgressCategoryController.setFragment(this);
 
         if (getArguments() != null) {
-            String broadcastMetadataStr = getArguments().getString(KEY_BROADCAST_METADATA);
-            if (!Strings.isNullOrEmpty(broadcastMetadataStr)) {
-                BluetoothLeBroadcastMetadata broadcastMetadata =
-                        BluetoothLeBroadcastMetadataExt.INSTANCE.convertToBroadcastMetadata(
-                                broadcastMetadataStr);
-                if (broadcastMetadata == null) {
-                    Log.w(TAG, "onAttach() broadcastMetadata is null!");
-                } else {
-                    mAudioStreamsProgressCategoryController.setSourceFromQrCode(broadcastMetadata);
-                }
+            var broadcastMetadata =
+                    getArguments()
+                            .getParcelable(
+                                    KEY_BROADCAST_METADATA, BluetoothLeBroadcastMetadata.class);
+            if (broadcastMetadata != null) {
+                mAudioStreamsProgressCategoryController.setSourceFromQrCode(
+                        broadcastMetadata, SourceOriginForLogging.QR_CODE_SCAN_OTHER);
+                mMetricsFeatureProvider.action(
+                        getContext(),
+                        SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED,
+                        SourceOriginForLogging.QR_CODE_SCAN_OTHER.ordinal());
             }
         }
     }
@@ -128,7 +127,12 @@
                             "onActivityResult() AudioStreamsProgressCategoryController is null!");
                     return;
                 }
-                mAudioStreamsProgressCategoryController.setSourceFromQrCode(source);
+                mAudioStreamsProgressCategoryController.setSourceFromQrCode(
+                        source, SourceOriginForLogging.QR_CODE_SCAN_SETTINGS);
+                mMetricsFeatureProvider.action(
+                        getContext(),
+                        SettingsEnums.ACTION_AUDIO_STREAM_QR_CODE_SCAN_SUCCEED,
+                        SourceOriginForLogging.QR_CODE_SCAN_SETTINGS.ordinal());
             }
         }
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
index 749220f..0777dd4 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java
@@ -19,12 +19,11 @@
 import static java.util.Collections.emptyList;
 
 import android.app.AlertDialog;
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.bluetooth.BluetoothLeBroadcastReceiveState;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
-import android.content.Intent;
-import android.provider.Settings;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -34,8 +33,10 @@
 
 import com.android.settings.R;
 import com.android.settings.bluetooth.Utils;
+import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment;
 import com.android.settings.connecteddevice.audiosharing.AudioSharingUtils;
 import com.android.settings.core.BasePreferenceController;
+import com.android.settings.core.SubSettingLauncher;
 import com.android.settingslib.bluetooth.BluetoothCallback;
 import com.android.settingslib.bluetooth.BluetoothUtils;
 import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -100,6 +101,7 @@
     private final ConcurrentHashMap<Integer, AudioStreamPreference> mBroadcastIdToPreferenceMap =
             new ConcurrentHashMap<>();
     private @Nullable BluetoothLeBroadcastMetadata mSourceFromQrCode;
+    private SourceOriginForLogging mSourceFromQrCodeOriginForLogging;
     @Nullable private AudioStreamsProgressCategoryPreference mCategoryPreference;
     @Nullable private AudioStreamsDashboardFragment mFragment;
 
@@ -149,11 +151,13 @@
         return mFragment;
     }
 
-    void setSourceFromQrCode(BluetoothLeBroadcastMetadata source) {
+    void setSourceFromQrCode(
+            BluetoothLeBroadcastMetadata source, SourceOriginForLogging sourceOriginForLogging) {
         if (DEBUG) {
             Log.d(TAG, "setSourceFromQrCode(): broadcastId " + source.getBroadcastId());
         }
         mSourceFromQrCode = source;
+        mSourceFromQrCodeOriginForLogging = sourceOriginForLogging;
     }
 
     void setScanning(boolean isScanning) {
@@ -196,7 +200,10 @@
                 broadcastIdFound,
                 (k, existingPreference) -> {
                     if (existingPreference == null) {
-                        return addNewPreference(source, AudioStreamState.SYNCED);
+                        return addNewPreference(
+                                source,
+                                AudioStreamState.SYNCED,
+                                SourceOriginForLogging.BROADCAST_SEARCH);
                     }
                     var fromState = existingPreference.getAudioStreamState();
                     if (fromState == AudioStreamState.WAIT_FOR_SYNC && mSourceFromQrCode != null) {
@@ -268,7 +275,9 @@
                         // Check nullability to bypass NullAway check.
                         if (mSourceFromQrCode != null) {
                             return addNewPreference(
-                                    mSourceFromQrCode, AudioStreamState.WAIT_FOR_SYNC);
+                                    mSourceFromQrCode,
+                                    AudioStreamState.WAIT_FOR_SYNC,
+                                    mSourceFromQrCodeOriginForLogging);
                         }
                     }
                     Log.w(
@@ -525,23 +534,27 @@
     }
 
     private AudioStreamPreference addNewPreference(
-            BluetoothLeBroadcastMetadata metadata, AudioStreamState state) {
-        var preference = AudioStreamPreference.fromMetadata(mContext, metadata);
+            BluetoothLeBroadcastMetadata metadata,
+            AudioStreamState state,
+            SourceOriginForLogging sourceOriginForLogging) {
+        var preference =
+                AudioStreamPreference.fromMetadata(mContext, metadata, sourceOriginForLogging);
         moveToState(preference, state);
         return preference;
     }
 
     private void moveToState(AudioStreamPreference preference, AudioStreamState state) {
-        AudioStreamStateHandler stateHandler = switch (state) {
-            case SYNCED -> SyncedState.getInstance();
-            case WAIT_FOR_SYNC -> WaitForSyncState.getInstance();
-            case ADD_SOURCE_WAIT_FOR_RESPONSE ->
-                    AddSourceWaitForResponseState.getInstance();
-            case ADD_SOURCE_BAD_CODE -> AddSourceBadCodeState.getInstance();
-            case ADD_SOURCE_FAILED -> AddSourceFailedState.getInstance();
-            case SOURCE_ADDED -> SourceAddedState.getInstance();
-            default -> throw new IllegalArgumentException("Unsupported state: " + state);
-        };
+        AudioStreamStateHandler stateHandler =
+                switch (state) {
+                    case SYNCED -> SyncedState.getInstance();
+                    case WAIT_FOR_SYNC -> WaitForSyncState.getInstance();
+                    case ADD_SOURCE_WAIT_FOR_RESPONSE ->
+                            AddSourceWaitForResponseState.getInstance();
+                    case ADD_SOURCE_BAD_CODE -> AddSourceBadCodeState.getInstance();
+                    case ADD_SOURCE_FAILED -> AddSourceFailedState.getInstance();
+                    case SOURCE_ADDED -> SourceAddedState.getInstance();
+                    default -> throw new IllegalArgumentException("Unsupported state: " + state);
+                };
 
         stateHandler.handleStateChange(preference, this, mAudioStreamsHelper);
 
@@ -566,9 +579,12 @@
                         mContext.getString(R.string.audio_streams_dialog_no_le_device_button))
                 .setRightButtonOnClickListener(
                         dialog -> {
-                            mContext.startActivity(
-                                    new Intent(Settings.ACTION_BLUETOOTH_SETTINGS)
-                                            .setPackage(mContext.getPackageName()));
+                            new SubSettingLauncher(mContext)
+                                    .setDestination(
+                                            ConnectedDeviceDashboardFragment.class.getName())
+                                    .setSourceMetricsCategory(
+                                            SettingsEnums.DIALOG_AUDIO_STREAM_MAIN_NO_LE_DEVICE)
+                                    .launch();
                             dialog.dismiss();
                         });
     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java
index 4b6dfa5..2bdc6ca 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeFragment.java
@@ -16,6 +16,7 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
+import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothLeBroadcastMetadata;
 import android.graphics.Bitmap;
 import android.os.Bundle;
@@ -45,8 +46,7 @@
 
     @Override
     public int getMetricsCategory() {
-        // TODO(chelseahao): update metrics id
-        return 0;
+        return SettingsEnums.AUDIO_STREAM_QR_CODE;
     }
 
     @Override
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeScanFragment.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeScanFragment.java
index 4af2eb5..e9b9ff3 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeScanFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsQrCodeScanFragment.java
@@ -248,6 +248,6 @@
 
     @Override
     public int getMetricsCategory() {
-        return SettingsEnums.LE_AUDIO_BROADCAST_SCAN_QR_CODE;
+        return SettingsEnums.AUDIO_STREAM_QR_CODE_SCAN;
     }
 }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsScanQrCodeController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsScanQrCodeController.java
index cd99dda..7f5c1e9 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsScanQrCodeController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsScanQrCodeController.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.connecteddevice.audiosharing.audiostreams;
 
-import android.app.settings.SettingsEnums;
 import android.bluetooth.BluetoothProfile;
 import android.content.Context;
 import android.util.Log;
@@ -111,7 +110,7 @@
                                 .setTitleRes(R.string.audio_streams_main_page_scan_qr_code_title)
                                 .setDestination(AudioStreamsQrCodeScanFragment.class.getName())
                                 .setResultListener(mFragment, REQUEST_SCAN_BT_BROADCAST_QR_CODE)
-                                .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
+                                .setSourceMetricsCategory(mFragment.getMetricsCategory())
                                 .launch();
                         return true;
                     }
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceAddedState.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceAddedState.java
index 4fdaf15..ee84429 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceAddedState.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceAddedState.java
@@ -57,6 +57,10 @@
                 context,
                 preference.getAudioStreamBroadcastId(),
                 String.valueOf(preference.getTitle()));
+        mMetricsFeatureProvider.action(
+                preference.getContext(),
+                SettingsEnums.ACTION_AUDIO_STREAM_JOIN_SUCCEED,
+                preference.getSourceOriginForLogging().ordinal());
     }
 
     @Override
@@ -79,8 +83,10 @@
                     .setTitleText(
                             p.getContext().getString(R.string.audio_streams_detail_page_title))
                     .setDestination(AudioStreamDetailsFragment.class.getName())
-                    // TODO(chelseahao): Add logging enum
-                    .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
+                    .setSourceMetricsCategory(
+                            controller.getFragment() == null
+                                    ? SettingsEnums.PAGE_UNKNOWN
+                                    : controller.getFragment().getMetricsCategory())
                     .setArguments(broadcast)
                     .launch();
             return true;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceOriginForLogging.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceOriginForLogging.java
new file mode 100644
index 0000000..6ca002a
--- /dev/null
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/SourceOriginForLogging.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2024 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.settings.connecteddevice.audiosharing.audiostreams;
+
+enum SourceOriginForLogging {
+    UNKNOWN,
+    QR_CODE_SCAN_SETTINGS,
+    QR_CODE_SCAN_OTHER,
+    BROADCAST_SEARCH,
+    REPOSITORY,
+}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncState.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncState.java
index 7e6d943..4554a4d 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncState.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncState.java
@@ -24,6 +24,7 @@
 
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
 
 import com.android.settings.R;
 import com.android.settings.core.SubSettingLauncher;
@@ -59,6 +60,11 @@
                         if (preference.isShown()
                                 && preference.getAudioStreamState() == getStateEnum()) {
                             controller.handleSourceLost(preference.getAudioStreamBroadcastId());
+                            mMetricsFeatureProvider.action(
+                                    preference.getContext(),
+                                    SettingsEnums
+                                            .ACTION_AUDIO_STREAM_JOIN_FAILED_WAIT_FOR_SYNC_TIMEOUT,
+                                    preference.getSourceOriginForLogging().ordinal());
                             ThreadUtils.postOnMainThread(
                                     () -> {
                                         if (controller.getFragment() != null) {
@@ -101,18 +107,19 @@
                 .setRightButtonOnClickListener(
                         dialog -> {
                             if (controller.getFragment() != null) {
-                                new SubSettingLauncher(context)
-                                        .setTitleRes(
-                                                R.string.audio_streams_main_page_scan_qr_code_title)
-                                        .setDestination(
-                                                AudioStreamsQrCodeScanFragment.class.getName())
-                                        .setResultListener(
-                                                controller.getFragment(),
-                                                REQUEST_SCAN_BT_BROADCAST_QR_CODE)
-                                        .setSourceMetricsCategory(SettingsEnums.PAGE_UNKNOWN)
-                                        .launch();
+                                launchQrCodeScanFragment(context, controller.getFragment());
                                 dialog.dismiss();
                             }
                         });
     }
+
+    private void launchQrCodeScanFragment(Context context, Fragment fragment) {
+        new SubSettingLauncher(context)
+                .setTitleRes(R.string.audio_streams_main_page_scan_qr_code_title)
+                .setDestination(AudioStreamsQrCodeScanFragment.class.getName())
+                .setResultListener(fragment, REQUEST_SCAN_BT_BROADCAST_QR_CODE)
+                .setSourceMetricsCategory(
+                        SettingsEnums.DIALOG_AUDIO_STREAM_MAIN_WAIT_FOR_SYNC_TIMEOUT)
+                .launch();
+    }
 }
diff --git a/src/com/android/settings/display/EvenDimmerPreferenceController.java b/src/com/android/settings/display/EvenDimmerPreferenceController.java
index 2a0f16d..6854213 100644
--- a/src/com/android/settings/display/EvenDimmerPreferenceController.java
+++ b/src/com/android/settings/display/EvenDimmerPreferenceController.java
@@ -50,11 +50,7 @@
                 com.android.internal.R.bool.config_evenDimmerEnabled);
 
         if (Flags.evenDimmer() && enabledInConfig) {
-            return Settings.System.getInt(mContext.getContentResolver(),
-                    Settings.System.SCREEN_BRIGHTNESS_MODE,
-                    Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL)
-                    == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC ? AVAILABLE
-                    : DISABLED_DEPENDENT_SETTING;
+            return AVAILABLE;
         } else {
             return UNSUPPORTED_ON_DEVICE;
         }
diff --git a/src/com/android/settings/notification/modes/IconOptionsProvider.java b/src/com/android/settings/notification/modes/IconOptionsProvider.java
new file mode 100644
index 0000000..288aff2
--- /dev/null
+++ b/src/com/android/settings/notification/modes/IconOptionsProvider.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 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.settings.notification.modes;
+
+import androidx.annotation.DrawableRes;
+
+import com.google.common.collect.ImmutableList;
+
+interface IconOptionsProvider {
+
+    ImmutableList<IconInfo> getIcons();
+
+    record IconInfo(@DrawableRes int resId, String description) { }
+}
diff --git a/src/com/android/settings/notification/modes/TempIconOptionsProvider.java b/src/com/android/settings/notification/modes/TempIconOptionsProvider.java
new file mode 100644
index 0000000..06c5c27
--- /dev/null
+++ b/src/com/android/settings/notification/modes/TempIconOptionsProvider.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 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.settings.notification.modes;
+
+import com.google.common.collect.ImmutableList;
+
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Objects;
+
+/** Temporary implementation of {@link IconOptionsProvider} until we have the real list. */
+class TempIconOptionsProvider implements IconOptionsProvider {
+    @Override
+    public ImmutableList<IconInfo> getIcons() {
+        return ImmutableList.copyOf(
+                Arrays.stream(com.android.internal.R.drawable.class.getFields())
+                        .filter(
+                                f -> Modifier.isStatic(f.getModifiers())
+                                        && Modifier.isFinal(f.getModifiers())
+                                        && f.getName().startsWith("ic_"))
+                        .limit(20)
+                        .map(f -> {
+                            try {
+                                return new IconInfo(f.getInt(null), f.getName());
+                            } catch (IllegalAccessException e) {
+                                return null;
+                            }
+                        })
+                        .filter(Objects::nonNull)
+                        .sorted(Comparator.comparing(IconInfo::resId).reversed())
+                        .toList());
+    }
+}
diff --git a/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java
index 5695fbc..8585234 100644
--- a/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeActionsPreferenceController.java
@@ -31,8 +31,6 @@
 
 class ZenModeActionsPreferenceController extends AbstractZenModePreferenceController {
 
-    private ActionButtonsPreference mPreference;
-
     ZenModeActionsPreferenceController(@NonNull Context context, @NonNull String key,
             @Nullable ZenModesBackend backend) {
         super(context, key, backend);
diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java b/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java
index 950849e..553d3eb 100644
--- a/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java
+++ b/src/com/android/settings/notification/modes/ZenModeIconPickerFragment.java
@@ -44,6 +44,7 @@
                 new ZenModeIconPickerIconPreferenceController(context, "current_icon", this,
                         mBackend),
                 new ZenModeIconPickerListPreferenceController(context, "icon_list", this,
-                        mBackend));
+                        // TODO: b/333901673 - Replace with correct icon list.
+                        new TempIconOptionsProvider(), mBackend));
     }
 }
diff --git a/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java
index b07c26f..fc991dc 100644
--- a/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java
+++ b/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceController.java
@@ -37,22 +37,18 @@
 
 import com.google.common.collect.ImmutableList;
 
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-
 class ZenModeIconPickerListPreferenceController extends AbstractZenModePreferenceController {
 
     private final DashboardFragment mFragment;
-    private IconAdapter mAdapter;
+    private final IconOptionsProvider mIconOptionsProvider;
+    @Nullable private IconAdapter mAdapter;
 
     ZenModeIconPickerListPreferenceController(@NonNull Context context, @NonNull String key,
-            @NonNull DashboardFragment fragment, @Nullable ZenModesBackend backend) {
+            @NonNull DashboardFragment fragment, @NonNull IconOptionsProvider iconOptionsProvider,
+            @Nullable ZenModesBackend backend) {
         super(context, key, backend);
         mFragment = fragment;
+        mIconOptionsProvider = iconOptionsProvider;
     }
 
     @Override
@@ -64,24 +60,7 @@
         }
 
         if (mAdapter == null) {
-            // TODO: b/333901673 - This is just an example; replace with correct list.
-            List<IconInfo> exampleIcons =
-                    Arrays.stream(android.R.drawable.class.getFields())
-                            .filter(
-                                    f -> Modifier.isStatic(f.getModifiers())
-                                            && f.getName().startsWith("ic_"))
-                            .sorted(Comparator.comparing(Field::getName))
-                            .limit(20)
-                            .map(f -> {
-                                try {
-                                    return new IconInfo(f.getInt(null), f.getName());
-                                } catch (IllegalAccessException e) {
-                                    return null;
-                                }
-                            })
-                            .filter(Objects::nonNull)
-                            .toList();
-            mAdapter = new IconAdapter(exampleIcons);
+            mAdapter = new IconAdapter(mIconOptionsProvider);
         }
         RecyclerView recyclerView = pref.findViewById(R.id.icon_list);
         recyclerView.setLayoutManager(new AutoFitGridLayoutManager(mContext));
@@ -103,8 +82,6 @@
         // Nothing to do, the current icon is shown in a different preference.
     }
 
-    private record IconInfo(@DrawableRes int resId, String description) { }
-
     private class IconHolder extends RecyclerView.ViewHolder {
 
         private final ImageView mImageView;
@@ -114,7 +91,7 @@
             mImageView = itemView.findViewById(R.id.icon_image_view);
         }
 
-        void bindIcon(IconInfo icon) {
+        void bindIcon(IconOptionsProvider.IconInfo icon) {
             mImageView.setImageDrawable(
                     IconUtil.makeIconCircle(itemView.getContext(), icon.resId()));
             itemView.setContentDescription(icon.description());
@@ -124,10 +101,10 @@
 
     private class IconAdapter extends RecyclerView.Adapter<IconHolder> {
 
-        private final ImmutableList<IconInfo> mIconResources;
+        private final ImmutableList<IconOptionsProvider.IconInfo> mIconResources;
 
-        private IconAdapter(List<IconInfo> iconOptions) {
-            mIconResources = ImmutableList.copyOf(iconOptions);
+        private IconAdapter(IconOptionsProvider iconOptionsProvider) {
+            mIconResources = iconOptionsProvider.getIcons();
         }
 
         @NonNull
diff --git a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
index 6b7a347..6b9252a 100644
--- a/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
+++ b/src/com/android/settings/privatespace/PrivateSpaceMaintainer.java
@@ -63,8 +63,9 @@
     @GuardedBy("this")
     private UserHandle mUserHandle;
     private final KeyguardManager mKeyguardManager;
-    /** This variable should be accessed via {@link #getBroadcastReceiver()} only. */
-    @Nullable private ProfileAvailabilityBroadcastReceiver mProfileAvailabilityBroadcastReceiver;
+    /** This variable should be accessed via {@link #getProfileBroadcastReceiver()} only. */
+    @Nullable
+    private ProfileBroadcastReceiver mProfileBroadcastReceiver;
 
     /** This is the default value for the hide private space entry point settings. */
     public static final int HIDE_PRIVATE_SPACE_ENTRY_POINT_DISABLED_VAL = 0;
@@ -150,7 +151,6 @@
             Log.i(TAG, "Deleting Private space with id: " + mUserHandle.getIdentifier());
             if (mUserManager.removeUser(mUserHandle)) {
                 Log.i(TAG, "Private space deleted");
-                unregisterBroadcastReceiver();
                 mUserHandle = null;
 
                 return ErrorDeletingPrivateSpace.DELETE_PS_ERROR_NONE;
@@ -394,13 +394,15 @@
                 && android.multiuser.Flags.enablePrivateSpaceFeatures();
     }
 
-    /** {@link BroadcastReceiver} which handles the private profile's availability related
-     * broadcasts.
+    /**
+     * {@link BroadcastReceiver} which handles the private profile's availability and deletion
+     * related broadcasts.
      */
-    private final class ProfileAvailabilityBroadcastReceiver extends BroadcastReceiver {
+    private final class ProfileBroadcastReceiver extends BroadcastReceiver {
         void register() {
             IntentFilter filter = new IntentFilter();
             filter.addAction(Intent.ACTION_PROFILE_UNAVAILABLE);
+            filter.addAction(Intent.ACTION_PROFILE_REMOVED);
             mContext.registerReceiver(/* receiver= */ this, filter, Context.RECEIVER_NOT_EXPORTED);
         }
 
@@ -412,6 +414,13 @@
         @Override
         public void onReceive(@NonNull Context context, @NonNull Intent intent) {
             UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class);
+            if (intent.getAction().equals(Intent.ACTION_PROFILE_REMOVED)) {
+                // This applies to all profiles getting removed, since there is no way to tell if
+                // it is a private profile that got removed.
+                removeSettingsAllTasks();
+                unregisterBroadcastReceiver();
+                return;
+            }
             if (!userHandle.equals(getPrivateProfileHandle())) {
                 Log.d(TAG, "Ignoring intent for non-private profile with user id "
                         + userHandle.getIdentifier());
@@ -428,7 +437,7 @@
                 || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
             return;
         }
-        var broadcastReceiver = getBroadcastReceiver();
+        var broadcastReceiver = getProfileBroadcastReceiver();
         if (broadcastReceiver == null) {
             return;
         }
@@ -440,17 +449,18 @@
                 || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
             return;
         }
-        if (mProfileAvailabilityBroadcastReceiver == null) {
+        if (mProfileBroadcastReceiver == null) {
             Log.w(TAG, "Requested to unregister when there is no receiver.");
             return;
         }
-        mProfileAvailabilityBroadcastReceiver.unregister();
-        mProfileAvailabilityBroadcastReceiver = null;
+        mProfileBroadcastReceiver.unregister();
+        mProfileBroadcastReceiver = null;
     }
 
-    /** Always use this getter to access {@link #mProfileAvailabilityBroadcastReceiver}. */
+    /** Always use this getter to access {@link #mProfileBroadcastReceiver}. */
     @VisibleForTesting
-    @Nullable synchronized ProfileAvailabilityBroadcastReceiver getBroadcastReceiver() {
+    @Nullable
+    synchronized ProfileBroadcastReceiver getProfileBroadcastReceiver() {
         if (!android.os.Flags.allowPrivateProfile()
                 || !android.multiuser.Flags.enablePrivateSpaceFeatures()) {
             return null;
@@ -459,16 +469,16 @@
             Log.e(TAG, "Cannot return a broadcast receiver when private space doesn't exist");
             return null;
         }
-        if (mProfileAvailabilityBroadcastReceiver == null) {
-            mProfileAvailabilityBroadcastReceiver = new ProfileAvailabilityBroadcastReceiver();
+        if (mProfileBroadcastReceiver == null) {
+            mProfileBroadcastReceiver = new ProfileBroadcastReceiver();
         }
-        return mProfileAvailabilityBroadcastReceiver;
+        return mProfileBroadcastReceiver;
     }
 
     /** This is purely for testing purpose only, and should not be used elsewhere. */
     @VisibleForTesting
     synchronized void resetBroadcastReceiver() {
-        mProfileAvailabilityBroadcastReceiver = null;
+        mProfileBroadcastReceiver = null;
     }
 
     private void removeSettingsAllTasks() {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseStateTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseStateTest.java
index 00357b4..6e5342b 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseStateTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AddSourceWaitForResponseStateTest.java
@@ -92,6 +92,8 @@
     @Test
     public void testPerformAction_metadataIsNotNull_addSource() {
         when(mMockPreference.getAudioStreamMetadata()).thenReturn(mMockMetadata);
+        when(mMockPreference.getSourceOriginForLogging())
+                .thenReturn(SourceOriginForLogging.UNKNOWN);
 
         mInstance.performAction(mMockPreference, mMockController, mMockHelper);
 
@@ -105,6 +107,8 @@
         when(mMockPreference.isShown()).thenReturn(true);
         when(mMockPreference.getAudioStreamState()).thenReturn(mInstance.getStateEnum());
         when(mMockPreference.getAudioStreamBroadcastId()).thenReturn(BROADCAST_ID);
+        when(mMockPreference.getSourceOriginForLogging())
+                .thenReturn(SourceOriginForLogging.UNKNOWN);
 
         mInstance.performAction(mMockPreference, mMockController, mMockHelper);
         ShadowLooper.idleMainLooper(ADD_SOURCE_WAIT_FOR_RESPONSE_TIMEOUT_MILLIS, TimeUnit.SECONDS);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java
index 456e45d3..c8f9358 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamPreferenceTest.java
@@ -107,7 +107,8 @@
     @Test
     public void setAudioStreamMetadata_shouldUpdateMetadata() {
         AudioStreamPreference p =
-                AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
+                AudioStreamPreference.fromMetadata(
+                        mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
         BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class);
         p.setAudioStreamMetadata(metadata);
 
@@ -117,7 +118,8 @@
     @Test
     public void setAudioStreamState_shouldUpdateState() {
         AudioStreamPreference p =
-                AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
+                AudioStreamPreference.fromMetadata(
+                        mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
         AudioStreamState state = AudioStreamState.SOURCE_ADDED;
         p.setAudioStreamState(state);
 
@@ -127,7 +129,8 @@
     @Test
     public void fromMetadata_shouldReturnBroadcastInfo() {
         AudioStreamPreference p =
-                AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
+                AudioStreamPreference.fromMetadata(
+                        mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
         assertThat(p.getAudioStreamBroadcastId()).isEqualTo(BROADCAST_ID);
         assertThat(p.getAudioStreamBroadcastName()).isEqualTo(BROADCAST_NAME);
         assertThat(p.getAudioStreamRssi()).isEqualTo(BROADCAST_RSSI);
@@ -152,7 +155,8 @@
     public void shouldHideSecondTarget_notEncrypted() {
         when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(false);
         AudioStreamPreference p =
-                AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
+                AudioStreamPreference.fromMetadata(
+                        mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
         assertThat(p.shouldHideSecondTarget()).isTrue();
     }
 
@@ -160,7 +164,8 @@
     public void shouldShowSecondTarget_encrypted() {
         when(mBluetoothLeBroadcastMetadata.isEncrypted()).thenReturn(true);
         AudioStreamPreference p =
-                AudioStreamPreference.fromMetadata(mContext, mBluetoothLeBroadcastMetadata);
+                AudioStreamPreference.fromMetadata(
+                        mContext, mBluetoothLeBroadcastMetadata, SourceOriginForLogging.UNKNOWN);
         assertThat(p.shouldHideSecondTarget()).isFalse();
     }
 
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncStateTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncStateTest.java
index 5297182..3eb07a4 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncStateTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/WaitForSyncStateTest.java
@@ -93,6 +93,8 @@
                 .thenReturn(AudioStreamsProgressCategoryController.AudioStreamState.WAIT_FOR_SYNC);
         when(mMockPreference.getAudioStreamBroadcastId()).thenReturn(1);
         when(mMockPreference.getAudioStreamMetadata()).thenReturn(mMockMetadata);
+        when(mMockPreference.getSourceOriginForLogging())
+                .thenReturn(SourceOriginForLogging.UNKNOWN);
 
         mInstance.performAction(mMockPreference, mMockController, mMockHelper);
         ShadowLooper.idleMainLooper(WAIT_FOR_SYNC_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
diff --git a/tests/robotests/src/com/android/settings/display/EvenDimmerPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/EvenDimmerPreferenceControllerTest.java
index e350587..11c4a79 100644
--- a/tests/robotests/src/com/android/settings/display/EvenDimmerPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/EvenDimmerPreferenceControllerTest.java
@@ -18,7 +18,6 @@
 
 
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
-import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
 import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -36,7 +35,6 @@
 import com.android.server.display.feature.flags.Flags;
 
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -65,7 +63,7 @@
 
     @RequiresFlagsDisabled(Flags.FLAG_EVEN_DIMMER)
     @Test
-    public void testGetAvailabilityStatus_flagOffconfigTrue() {
+    public void testGetAvailabilityStatus_flagOffConfigTrue() {
         when(mContext.getResources()).thenReturn(mResources);
         when(mResources.getBoolean(
                 com.android.internal.R.bool.config_evenDimmerEnabled)).thenReturn(true);
@@ -86,7 +84,6 @@
                 Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false
     }
 
-    @Ignore("b/331324279")
     @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
     @Test
     public void testGetAvailabilityStatus_flagOnConfigTrue() {
@@ -99,10 +96,24 @@
         assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
     }
 
-    @Ignore("b/331324279")
+
+    @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
+    @Test
+    public void testGetAvailabilityStatus_flagOnConfigFalse() {
+        when(mContext.getResources()).thenReturn(mResources);
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled)).thenReturn(false);
+        // setup
+        mController = new EvenDimmerPreferenceController(mContext, "key");
+
+        assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
+    }
+
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
     public void testSetChecked_enable() throws Settings.SettingNotFoundException {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled)).thenReturn(true);
         mController.setChecked(true);
         assertThat(Settings.Secure.getFloat(mContext.getContentResolver(),
                 Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(1.0f); // true
@@ -111,23 +122,10 @@
     @Test
     @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
     public void testSetChecked_disable() throws Settings.SettingNotFoundException {
+        when(mResources.getBoolean(
+                com.android.internal.R.bool.config_evenDimmerEnabled)).thenReturn(true);
         mController.setChecked(false);
         assertThat(Settings.Secure.getFloat(mContext.getContentResolver(),
                 Settings.Secure.EVEN_DIMMER_ACTIVATED)).isEqualTo(0.0f); // false
     }
-
-    @Ignore("b/331324279")
-    @Test
-    @RequiresFlagsEnabled(Flags.FLAG_EVEN_DIMMER)
-    public void testDisabledIfAutobrightnessIsOff() {
-        // Autobrightness off
-        Settings.System.putInt(mContext.getContentResolver(),
-                Settings.System.SCREEN_BRIGHTNESS_MODE,
-                Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
-        // Try turn controller on
-        mController.setChecked(true);
-
-        assertThat(mController.getAvailabilityStatus()).isEqualTo(
-                DISABLED_DEPENDENT_SETTING);
-    }
 }
diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
index c0fbe15..5f7ffa2 100644
--- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeIconPickerListPreferenceControllerTest.java
@@ -34,6 +34,8 @@
 import com.android.settings.dashboard.DashboardFragment;
 import com.android.settingslib.widget.LayoutPreference;
 
+import com.google.common.collect.ImmutableList;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -61,7 +63,8 @@
 
         DashboardFragment fragment = mock(DashboardFragment.class);
         mController = new ZenModeIconPickerListPreferenceController(
-                RuntimeEnvironment.getApplication(), "icon_list", fragment, mBackend);
+                RuntimeEnvironment.getApplication(), "icon_list", fragment,
+                new TestIconOptionsProvider(), mBackend);
 
         mRecyclerView = new RecyclerView(context);
         mRecyclerView.setId(R.id.icon_list);
@@ -75,7 +78,7 @@
         mController.displayPreference(mPreferenceScreen);
 
         assertThat(mRecyclerView.getAdapter()).isNotNull();
-        assertThat(mRecyclerView.getAdapter().getItemCount()).isEqualTo(20);
+        assertThat(mRecyclerView.getAdapter().getItemCount()).isEqualTo(3);
     }
 
     @Test
@@ -88,4 +91,15 @@
         verify(mBackend).updateMode(captor.capture());
         assertThat(captor.getValue().getRule().getIconResId()).isEqualTo(R.drawable.ic_android);
     }
+
+    private static class TestIconOptionsProvider implements IconOptionsProvider {
+
+        @Override
+        public ImmutableList<IconInfo> getIcons() {
+            return ImmutableList.of(
+                    new IconInfo(R.drawable.ic_android, "android"),
+                    new IconInfo(R.drawable.ic_info, "info"),
+                    new IconInfo(R.drawable.ic_hearing, "hearing"));
+        }
+    }
 }
diff --git a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
index 2463d4c..7095235 100644
--- a/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
+++ b/tests/unit/src/com/android/settings/privatespace/PrivateSpaceMaintainerTest.java
@@ -215,7 +215,7 @@
         privateSpaceMaintainer.deletePrivateSpace();
         privateSpaceMaintainer.createPrivateSpace();
         // test that no exception is thrown, which would indicate that the receiver was registered.
-        mContext.unregisterReceiver(privateSpaceMaintainer.getBroadcastReceiver());
+        mContext.unregisterReceiver(privateSpaceMaintainer.getProfileBroadcastReceiver());
         privateSpaceMaintainer.resetBroadcastReceiver();
     }
 
@@ -227,7 +227,7 @@
                 PrivateSpaceMaintainer.getInstance(mContext);
         privateSpaceMaintainer.createPrivateSpace();
         privateSpaceMaintainer.deletePrivateSpace();
-        assertThat(privateSpaceMaintainer.getBroadcastReceiver()).isNull();
+        assertThat(privateSpaceMaintainer.getProfileBroadcastReceiver()).isNull();
     }
 
     /**