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

Commit 14a55ebd authored by Betty Chang's avatar Betty Chang Committed by Android (Google) Code Review
Browse files

Merge "To set the click listener when the user clicks the switch broadcast button" into udc-dev

parents 2357ec0d e2af9857
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -350,6 +350,7 @@
    <protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
    <protected-broadcast android:name="com.android.settings.flashlight.action.FLASHLIGHT_CHANGED" />
    <protected-broadcast android:name="com.android.systemui.action.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG" />
    <protected-broadcast android:name="com.android.systemui.STARTED" />

    <application
+216 −4
Original line number Diff line number Diff line
@@ -16,8 +16,15 @@

package com.android.systemui.bluetooth;

import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -28,11 +35,18 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.MediaOutputConstants;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.media.controls.util.MediaDataUtils;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;
import com.android.systemui.statusbar.phone.SystemUIDialog;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * Dialog for showing le audio broadcasting dialog.
 */
@@ -40,17 +54,91 @@ public class BroadcastDialog extends SystemUIDialog {

    private static final String TAG = "BroadcastDialog";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    private static final int HANDLE_BROADCAST_FAILED_DELAY = 3000;

    private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());

    private Context mContext;
    private UiEventLogger mUiEventLogger;
    @VisibleForTesting
    protected View mDialogView;
    private MediaOutputDialogFactory mMediaOutputDialogFactory;
    private LocalBluetoothManager mLocalBluetoothManager;
    private BroadcastSender mBroadcastSender;
    private String mCurrentBroadcastApp;
    private String mOutputPackageName;
    private Executor mExecutor;
    private boolean mShouldLaunchLeBroadcastDialog;
    private Button mSwitchBroadcast;

    private final BluetoothLeBroadcast.Callback mBroadcastCallback =
            new BluetoothLeBroadcast.Callback() {
            @Override
            public void onBroadcastStarted(int reason, int broadcastId) {
                if (DEBUG) {
                    Log.d(TAG, "onBroadcastStarted(), reason = " + reason
                            + ", broadcastId = " + broadcastId);
                }
                mMainThreadHandler.post(() -> handleLeBroadcastStarted());
            }

            @Override
            public void onBroadcastStartFailed(int reason) {
                if (DEBUG) {
                    Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
                }
                mMainThreadHandler.postDelayed(() -> handleLeBroadcastStartFailed(),
                        HANDLE_BROADCAST_FAILED_DELAY);
            }

            @Override
            public void onBroadcastMetadataChanged(int broadcastId,
                    @NonNull BluetoothLeBroadcastMetadata metadata) {
                if (DEBUG) {
                    Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId
                            + ", metadata = " + metadata);
                }
                mMainThreadHandler.post(() -> handleLeBroadcastMetadataChanged());
            }

            @Override
            public void onBroadcastStopped(int reason, int broadcastId) {
                if (DEBUG) {
                    Log.d(TAG, "onBroadcastStopped(), reason = " + reason
                            + ", broadcastId = " + broadcastId);
                }
                mMainThreadHandler.post(() -> handleLeBroadcastStopped());
            }

            @Override
            public void onBroadcastStopFailed(int reason) {
                if (DEBUG) {
                    Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
                }
                mMainThreadHandler.postDelayed(() -> handleLeBroadcastStopFailed(),
                        HANDLE_BROADCAST_FAILED_DELAY);
            }

            @Override
            public void onBroadcastUpdated(int reason, int broadcastId) {
            }

            @Override
            public void onBroadcastUpdateFailed(int reason, int broadcastId) {
            }

            @Override
            public void onPlaybackStarted(int reason, int broadcastId) {
            }

            @Override
            public void onPlaybackStopped(int reason, int broadcastId) {
            }
        };

    public BroadcastDialog(Context context, MediaOutputDialogFactory mediaOutputDialogFactory,
            String currentBroadcastApp, String outputPkgName, UiEventLogger uiEventLogger) {
            LocalBluetoothManager localBluetoothManager, String currentBroadcastApp,
            String outputPkgName, UiEventLogger uiEventLogger, BroadcastSender broadcastSender) {
        super(context);
        if (DEBUG) {
            Log.d(TAG, "Init BroadcastDialog");
@@ -58,9 +146,18 @@ public class BroadcastDialog extends SystemUIDialog {

        mContext = getContext();
        mMediaOutputDialogFactory = mediaOutputDialogFactory;
        mLocalBluetoothManager = localBluetoothManager;
        mCurrentBroadcastApp = currentBroadcastApp;
        mOutputPackageName = outputPkgName;
        mUiEventLogger = uiEventLogger;
        mExecutor = Executors.newSingleThreadExecutor();
        mBroadcastSender = broadcastSender;
    }

    @Override
    public void onStart() {
        super.onStart();
        registerBroadcastCallBack(mExecutor, mBroadcastCallback);
    }

    @Override
@@ -84,11 +181,12 @@ public class BroadcastDialog extends SystemUIDialog {
        subTitle.setText(mContext.getString(
                R.string.bt_le_audio_broadcast_dialog_sub_title, switchBroadcastApp));

        Button switchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
        mSwitchBroadcast = mDialogView.requireViewById(R.id.switch_broadcast);
        Button changeOutput = mDialogView.requireViewById(R.id.change_output);
        Button cancelBtn = mDialogView.requireViewById(R.id.cancel);
        switchBroadcast.setText(mContext.getString(
                R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp));
        mSwitchBroadcast.setText(mContext.getString(
                R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp), null);
        mSwitchBroadcast.setOnClickListener((view) -> startSwitchBroadcast());
        changeOutput.setOnClickListener((view) -> {
            mMediaOutputDialogFactory.create(mOutputPackageName, true, null);
            dismiss();
@@ -101,6 +199,79 @@ public class BroadcastDialog extends SystemUIDialog {
        });
    }

    @Override
    public void onStop() {
        super.onStop();
        unregisterBroadcastCallBack(mBroadcastCallback);
    }

    void refreshSwitchBroadcastButton() {
        String switchBroadcastApp = MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
                mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name));
        mSwitchBroadcast.setText(mContext.getString(
                R.string.bt_le_audio_broadcast_dialog_switch_app, switchBroadcastApp), null);
        mSwitchBroadcast.setEnabled(true);
    }

    private void startSwitchBroadcast() {
        if (DEBUG) {
            Log.d(TAG, "startSwitchBroadcast");
        }
        mSwitchBroadcast.setText(R.string.media_output_broadcast_starting);
        mSwitchBroadcast.setEnabled(false);
        //Stop the current Broadcast
        if (!stopBluetoothLeBroadcast()) {
            handleLeBroadcastStopFailed();
            return;
        }
    }

    private void registerBroadcastCallBack(
            @NonNull @CallbackExecutor Executor executor,
            @NonNull BluetoothLeBroadcast.Callback callback) {
        LocalBluetoothLeBroadcast broadcast =
                mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        if (broadcast == null) {
            Log.d(TAG, "The broadcast profile is null");
            return;
        }
        broadcast.registerServiceCallBack(executor, callback);
    }

    private void unregisterBroadcastCallBack(@NonNull BluetoothLeBroadcast.Callback callback) {
        LocalBluetoothLeBroadcast broadcast =
                mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        if (broadcast == null) {
            Log.d(TAG, "The broadcast profile is null");
            return;
        }
        broadcast.unregisterServiceCallBack(callback);
    }

    boolean startBluetoothLeBroadcast() {
        LocalBluetoothLeBroadcast broadcast =
                mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        if (broadcast == null) {
            Log.d(TAG, "The broadcast profile is null");
            return false;
        }
        String switchBroadcastApp = MediaDataUtils.getAppLabel(mContext, mOutputPackageName,
                mContext.getString(R.string.bt_le_audio_broadcast_dialog_unknown_name));
        broadcast.startBroadcast(switchBroadcastApp, /*language*/ null);
        return true;
    }

    boolean stopBluetoothLeBroadcast() {
        LocalBluetoothLeBroadcast broadcast =
                mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        if (broadcast == null) {
            Log.d(TAG, "The broadcast profile is null");
            return false;
        }
        broadcast.stopLatestBroadcast();
        return true;
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
@@ -125,4 +296,45 @@ public class BroadcastDialog extends SystemUIDialog {
        }
    }

    void handleLeBroadcastStarted() {
        // Waiting for the onBroadcastMetadataChanged. The UI launchs the broadcast dialog when
        // the metadata is ready.
        mShouldLaunchLeBroadcastDialog = true;
    }

    private void handleLeBroadcastStartFailed() {
        mSwitchBroadcast.setText(R.string.media_output_broadcast_start_failed);
        mSwitchBroadcast.setEnabled(false);
        refreshSwitchBroadcastButton();
    }

    void handleLeBroadcastMetadataChanged() {
        if (mShouldLaunchLeBroadcastDialog) {
            startLeBroadcastDialog();
            mShouldLaunchLeBroadcastDialog = false;
        }
    }

    @VisibleForTesting
    void handleLeBroadcastStopped() {
        mShouldLaunchLeBroadcastDialog = false;
        if (!startBluetoothLeBroadcast()) {
            handleLeBroadcastStartFailed();
            return;
        }
    }

    private void handleLeBroadcastStopFailed() {
        mSwitchBroadcast.setText(R.string.media_output_broadcast_start_failed);
        mSwitchBroadcast.setEnabled(false);
        refreshSwitchBroadcastButton();
    }

    private void startLeBroadcastDialog() {
        mBroadcastSender.sendBroadcast(new Intent()
                .setPackage(mContext.getPackageName())
                .setAction(MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG)
                .putExtra(MediaOutputConstants.EXTRA_PACKAGE_NAME, mOutputPackageName));
        dismiss();
    }
}
+12 −2
Original line number Diff line number Diff line
@@ -16,11 +16,14 @@

package com.android.systemui.bluetooth;

import android.annotation.Nullable;
import android.content.Context;
import android.view.View;

import com.android.internal.logging.UiEventLogger;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.media.dialog.MediaOutputDialogFactory;

@@ -36,15 +39,21 @@ public class BroadcastDialogController {
    private UiEventLogger mUiEventLogger;
    private DialogLaunchAnimator mDialogLaunchAnimator;
    private MediaOutputDialogFactory mMediaOutputDialogFactory;
    private final LocalBluetoothManager mLocalBluetoothManager;
    private BroadcastSender mBroadcastSender;

    @Inject
    public BroadcastDialogController(Context context, UiEventLogger uiEventLogger,
            DialogLaunchAnimator dialogLaunchAnimator,
            MediaOutputDialogFactory mediaOutputDialogFactory) {
            MediaOutputDialogFactory mediaOutputDialogFactory,
            @Nullable LocalBluetoothManager localBluetoothManager,
            BroadcastSender broadcastSender) {
        mContext = context;
        mUiEventLogger = uiEventLogger;
        mDialogLaunchAnimator = dialogLaunchAnimator;
        mMediaOutputDialogFactory = mediaOutputDialogFactory;
        mLocalBluetoothManager = localBluetoothManager;
        mBroadcastSender = broadcastSender;
    }

    /** Creates a [BroadcastDialog] for the user to switch broadcast or change the output device
@@ -55,7 +64,8 @@ public class BroadcastDialogController {
    public void createBroadcastDialog(String currentBroadcastAppName, String outputPkgName,
            boolean aboveStatusBar, View view) {
        BroadcastDialog broadcastDialog = new BroadcastDialog(mContext, mMediaOutputDialogFactory,
                currentBroadcastAppName, outputPkgName, mUiEventLogger);
                mLocalBluetoothManager, currentBroadcastAppName, outputPkgName, mUiEventLogger,
                mBroadcastSender);
        if (view != null) {
            mDialogLaunchAnimator.showFromView(broadcastDialog, view);
        } else {
+1 −1
Original line number Diff line number Diff line
@@ -996,7 +996,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
                mAudioManager, mPowerExemptionManager, mKeyGuardManager, mFeatureFlags);
        MediaOutputBroadcastDialog dialog = new MediaOutputBroadcastDialog(mContext, true,
                broadcastSender, controller);
        mDialogLaunchAnimator.showFromView(dialog, mediaOutputDialog);
        dialog.show();
    }

    String getBroadcastName() {
+2 −1
Original line number Diff line number Diff line
@@ -62,7 +62,8 @@ class MediaOutputDialogReceiver @Inject constructor(

    private fun launchMediaOutputBroadcastDialogIfPossible(packageName: String?) {
        if (!packageName.isNullOrEmpty()) {
            mediaOutputBroadcastDialogFactory.create(packageName, false)
            mediaOutputBroadcastDialogFactory.create(
                    packageName, aboveStatusBar = true, view = null)
        } else if (DEBUG) {
            Log.e(TAG, "Unable to launch media output broadcast dialog. Package name is empty.")
        }
Loading