Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cac4114 authored by Chelsea Hao's avatar Chelsea Hao Committed by Android (Google) Code Review
Browse files

Merge changes I9036e560,Ieb735d39,Ia78b1fe1,I91d9a45a into main

* changes:
  [Audiosharing] Created test for the name and password preferences.
  [Audiosharing] Created test for the main controller.
  [Audiosharing] Listen to `onProfileConnectionStateChanged` of LE_AUDIO_BROADCAST_ASSISTANT to be more precise on device connection status upon bluetooth on/off. Also increase test coverage.
  [Audiosharing] Increase test coverage for audio stream states.
parents 0bd8a5d2 4afef7ee
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -95,14 +95,14 @@ public class AudioSharingNamePreference extends ValidatedEditTextPreference {
    }

    private void configureInvisibleStateForQrCodeIcon(ImageButton shareButton, View divider) {
        divider.setVisibility(View.INVISIBLE);
        shareButton.setVisibility(View.INVISIBLE);
        divider.setVisibility(View.GONE);
        shareButton.setVisibility(View.GONE);
        shareButton.setOnClickListener(null);
    }

    private void launchAudioSharingQrCodeFragment() {
        new SubSettingLauncher(getContext())
                .setTitleText(getContext().getString(R.string.audio_streams_qr_code_page_title))
                .setTitleRes(R.string.audio_streams_qr_code_page_title)
                .setDestination(AudioStreamsQrCodeFragment.class.getName())
                .setSourceMetricsCategory(SettingsEnums.AUDIO_SHARING_SETTINGS)
                .launch();
+3 −1
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference;
@@ -56,7 +57,8 @@ public class AudioSharingNamePreferenceController extends BasePreferenceControll
    private static final boolean DEBUG = BluetoothUtils.D;
    private static final String PREF_KEY = "audio_sharing_stream_name";

    private final BluetoothLeBroadcast.Callback mBroadcastCallback =
    @VisibleForTesting
    final BluetoothLeBroadcast.Callback mBroadcastCallback =
            new BluetoothLeBroadcast.Callback() {
                @Override
                public void onBroadcastMetadataChanged(
+79 −14
Original line number Diff line number Diff line
@@ -19,12 +19,19 @@ package com.android.settings.connecteddevice.audiosharing;
import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.isBroadcasting;

import android.app.settings.SettingsEnums;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.Looper;
import android.provider.Settings;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.PreferenceScreen;

import com.android.settings.R;
@@ -41,15 +48,19 @@ import java.nio.charset.StandardCharsets;

public class AudioSharingPasswordPreferenceController extends BasePreferenceController
        implements ValidatedEditTextPreference.Validator,
                AudioSharingPasswordPreference.OnDialogEventListener {

                AudioSharingPasswordPreference.OnDialogEventListener,
                DefaultLifecycleObserver {
    private static final String TAG = "AudioSharingPasswordPreferenceController";
    private static final String PREF_KEY = "audio_sharing_stream_password";
    private static final String SHARED_PREF_NAME = "audio_sharing_settings";
    private static final String SHARED_PREF_KEY = "default_password";
    @Nullable private final ContentResolver mContentResolver;
    @Nullable private final SharedPreferences mSharedPref;
    @Nullable private final LocalBluetoothManager mBtManager;
    @Nullable private final LocalBluetoothLeBroadcast mBroadcast;
    @Nullable private AudioSharingPasswordPreference mPreference;
    private final ContentObserver mSettingsObserver;
    private final SharedPreferences.OnSharedPreferenceChangeListener mSharedPrefChangeListener;
    private final AudioSharingPasswordValidator mAudioSharingPasswordValidator;
    private final MetricsFeatureProvider mMetricsFeatureProvider;

@@ -61,9 +72,44 @@ public class AudioSharingPasswordPreferenceController extends BasePreferenceCont
                        ? mBtManager.getProfileManager().getLeAudioBroadcastProfile()
                        : null;
        mAudioSharingPasswordValidator = new AudioSharingPasswordValidator();
        mContentResolver = context.getContentResolver();
        mSettingsObserver = new PasswordSettingsObserver();
        mSharedPref = context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        mSharedPrefChangeListener = new PasswordSharedPrefChangeListener();
        mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
    }

    @Override
    public void onStart(@NonNull LifecycleOwner owner) {
        if (!isAvailable()) {
            Log.d(TAG, "Feature is not available.");
            return;
        }
        if (mContentResolver != null) {
            mContentResolver.registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.BLUETOOTH_LE_BROADCAST_CODE),
                    false,
                    mSettingsObserver);
        }
        if (mSharedPref != null) {
            mSharedPref.registerOnSharedPreferenceChangeListener(mSharedPrefChangeListener);
        }
    }

    @Override
    public void onStop(@NonNull LifecycleOwner owner) {
        if (!isAvailable()) {
            Log.d(TAG, "Feature is not available.");
            return;
        }
        if (mContentResolver != null) {
            mContentResolver.unregisterContentObserver(mSettingsObserver);
        }
        if (mSharedPref != null) {
            mSharedPref.unregisterOnSharedPreferenceChangeListener(mSharedPrefChangeListener);
        }
    }

    @Override
    public int getAvailabilityStatus() {
        return AudioSharingUtils.isFeatureEnabled() ? AVAILABLE : UNSUPPORTED_ON_DEVICE;
@@ -125,7 +171,6 @@ public class AudioSharingPasswordPreferenceController extends BasePreferenceCont
                            persistDefaultPassword(mContext, password);
                            mBroadcast.setBroadcastCode(
                                    isPublicBroadcast ? new byte[0] : password.getBytes());
                            updatePreference();
                            mMetricsFeatureProvider.action(
                                    mContext,
                                    SettingsEnums.ACTION_AUDIO_STREAM_PASSWORD_UPDATED,
@@ -164,32 +209,52 @@ public class AudioSharingPasswordPreferenceController extends BasePreferenceCont
                        });
    }

    private static void persistDefaultPassword(Context context, String defaultPassword) {
        if (getDefaultPassword(context).equals(defaultPassword)) {
    private class PasswordSettingsObserver extends ContentObserver {
        PasswordSettingsObserver() {
            super(new Handler(Looper.getMainLooper()));
        }

        @Override
        public void onChange(boolean selfChange) {
            Log.d(TAG, "onChange, broadcast password has been changed");
            updatePreference();
        }
    }

    private class PasswordSharedPrefChangeListener
            implements SharedPreferences.OnSharedPreferenceChangeListener {
        @Override
        public void onSharedPreferenceChanged(
                SharedPreferences sharedPreferences, @Nullable String key) {
            if (!SHARED_PREF_KEY.equals(key)) {
                return;
            }
            Log.d(TAG, "onSharedPreferenceChanged, default password has been changed");
            updatePreference();
        }
    }

        SharedPreferences sharedPref =
                context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        if (sharedPref == null) {
    private void persistDefaultPassword(Context context, String defaultPassword) {
        if (getDefaultPassword(context).equals(defaultPassword)) {
            return;
        }
        if (mSharedPref == null) {
            Log.w(TAG, "persistDefaultPassword(): sharedPref is empty!");
            return;
        }

        SharedPreferences.Editor editor = sharedPref.edit();
        SharedPreferences.Editor editor = mSharedPref.edit();
        editor.putString(SHARED_PREF_KEY, defaultPassword);
        editor.apply();
    }

    private static String getDefaultPassword(Context context) {
        SharedPreferences sharedPref =
                context.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);
        if (sharedPref == null) {
    private String getDefaultPassword(Context context) {
        if (mSharedPref == null) {
            Log.w(TAG, "getDefaultPassword(): sharedPref is empty!");
            return "";
        }

        String value = sharedPref.getString(SHARED_PREF_KEY, "");
        String value = mSharedPref.getString(SHARED_PREF_KEY, "");
        if (value != null && value.isEmpty()) {
            Log.w(TAG, "getDefaultPassword(): default password is empty!");
        }
+2 −1
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ class AddSourceWaitForResponseState extends AudioStreamStateHandler {

    @Nullable private static AddSourceWaitForResponseState sInstance = null;

    private AddSourceWaitForResponseState() {}
    @VisibleForTesting
    AddSourceWaitForResponseState() {}

    static AddSourceWaitForResponseState getInstance() {
        if (sInstance == null) {
+6 −1
Original line number Diff line number Diff line
@@ -35,10 +35,10 @@ class AudioStreamStateHandler {
    private static final boolean DEBUG = BluetoothUtils.D;
    @VisibleForTesting static final int EMPTY_STRING_RES = 0;

    final AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance();
    final Handler mHandler = new Handler(Looper.getMainLooper());
    final MetricsFeatureProvider mMetricsFeatureProvider =
            FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
    AudioStreamsRepository mAudioStreamsRepository = AudioStreamsRepository.getInstance();

    AudioStreamStateHandler() {}

@@ -112,4 +112,9 @@ class AudioStreamStateHandler {
    AudioStreamsProgressCategoryController.AudioStreamState getStateEnum() {
        return AudioStreamsProgressCategoryController.AudioStreamState.UNKNOWN;
    }

    @VisibleForTesting
    void setAudioStreamsRepositoryForTesting(AudioStreamsRepository repository) {
        mAudioStreamsRepository = repository;
    }
}
Loading