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

Commit f2373017 authored by Bishoy Gendy's avatar Bishoy Gendy
Browse files

Add new api for showing media output switcher dialog.

Bug: 258532462
Test: Using androidx sample app as it's a partial cl of ag/20859924.
Change-Id: I2ad346de8558563db6decbbe626b522a88a552f5
parent f5bf900a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -338,4 +338,11 @@ oneway interface IStatusBar
     * @param leftOrTop indicates where the stage split is.
     */
    void enterStageSplitFromRunningApp(boolean leftOrTop);

    /**
     * Shows the media output switcher dialog.
     *
     * @param packageName of the session for which the output switcher is shown.
     */
    void showMediaOutputSwitcher(String packageName);
}
+7 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import com.android.systemui.globalactions.GlobalActionsComponent
import com.android.systemui.keyboard.KeyboardUI
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.log.SessionTracker
import com.android.systemui.media.dialog.MediaOutputSwitcherDialogUI
import com.android.systemui.media.RingtonePlayer
import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver
@@ -217,6 +218,12 @@ abstract class SystemUICoreStartableModule {
    @ClassKey(ToastUI::class)
    abstract fun bindToastUI(service: ToastUI): CoreStartable

    /** Inject into MediaOutputSwitcherDialogUI.  */
    @Binds
    @IntoMap
    @ClassKey(MediaOutputSwitcherDialogUI::class)
    abstract fun MediaOutputSwitcherDialogUI(sysui: MediaOutputSwitcherDialogUI): CoreStartable

    /** Inject into VolumeUI.  */
    @Binds
    @IntoMap
+5 −0
Original line number Diff line number Diff line
@@ -506,6 +506,11 @@ object Flags {
    @JvmField
    val OUTPUT_SWITCHER_DEVICE_STATUS = unreleasedFlag(2502, "output_switcher_device_status")

    // TODO(b/20911786): Tracking Bug
    @JvmField
    val OUTPUT_SWITCHER_SHOW_API_ENABLED =
        unreleasedFlag(2503, "output_switcher_show_api_enabled", teamfood = true)

    // TODO(b259590361): Tracking bug
    val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
}
+71 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.systemui.media.dialog;

import android.annotation.MainThread;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.statusbar.CommandQueue;

import javax.inject.Inject;

/** Controls display of media output switcher. */
@SysUISingleton
public class MediaOutputSwitcherDialogUI implements CoreStartable, CommandQueue.Callbacks {

    private static final String TAG = "MediaOutputSwitcherDialogUI";

    private final CommandQueue mCommandQueue;
    private final MediaOutputDialogFactory mMediaOutputDialogFactory;
    private final FeatureFlags mFeatureFlags;

    @Inject
    public MediaOutputSwitcherDialogUI(
            Context context,
            CommandQueue commandQueue,
            MediaOutputDialogFactory mediaOutputDialogFactory,
            FeatureFlags featureFlags) {
        mCommandQueue = commandQueue;
        mMediaOutputDialogFactory = mediaOutputDialogFactory;
        mFeatureFlags = featureFlags;
    }

    @Override
    public void start() {
        if (mFeatureFlags.isEnabled(Flags.OUTPUT_SWITCHER_SHOW_API_ENABLED)) {
            mCommandQueue.addCallback(this);
        } else {
            Log.w(TAG, "Show media output switcher is not enabled.");
        }
    }

    @Override
    @MainThread
    public void showMediaOutputSwitcher(String packageName) {
        if (!TextUtils.isEmpty(packageName)) {
            mMediaOutputDialogFactory.create(packageName, false, null);
        } else {
            Log.e(TAG, "Unable to launch media output dialog. Package name is empty.");
        }
    }
}
+28 −0
Original line number Diff line number Diff line
@@ -45,12 +45,14 @@ import android.hardware.fingerprint.IUdfpsHbmListener;
import android.inputmethodservice.InputMethodService.BackDispositionMode;
import android.media.INearbyMediaDevicesProvider;
import android.media.MediaRoute2Info;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
import android.util.Pair;
import android.util.SparseArray;
@@ -168,6 +170,7 @@ public class CommandQueue extends IStatusBar.Stub implements
    private static final int MSG_SHOW_REAR_DISPLAY_DIALOG = 69 << MSG_SHIFT;
    private static final int MSG_GO_TO_FULLSCREEN_FROM_SPLIT = 70 << MSG_SHIFT;
    private static final int MSG_ENTER_STAGE_SPLIT_FROM_RUNNING_APP = 71 << MSG_SHIFT;
    private static final int MSG_SHOW_MEDIA_OUTPUT_SWITCHER = 72 << MSG_SHIFT;

    public static final int FLAG_EXCLUDE_NONE = 0;
    public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -492,6 +495,11 @@ public class CommandQueue extends IStatusBar.Stub implements
         * @see IStatusBar#enterStageSplitFromRunningApp
         */
        default void enterStageSplitFromRunningApp(boolean leftOrTop) {}

        /**
         * @see IStatusBar#showMediaOutputSwitcher
         */
        default void showMediaOutputSwitcher(String packageName) {}
    }

    public CommandQueue(Context context) {
@@ -1261,6 +1269,19 @@ public class CommandQueue extends IStatusBar.Stub implements
        }
    }

    @Override
    public void showMediaOutputSwitcher(String packageName) {
        int callingUid = Binder.getCallingUid();
        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
            throw new SecurityException("Call only allowed from system server.");
        }
        synchronized (mLock) {
            SomeArgs args = SomeArgs.obtain();
            args.arg1 = packageName;
            mHandler.obtainMessage(MSG_SHOW_MEDIA_OUTPUT_SWITCHER, args).sendToTarget();
        }
    }

    @Override
    public void requestAddTile(
            @NonNull ComponentName componentName,
@@ -1777,6 +1798,13 @@ public class CommandQueue extends IStatusBar.Stub implements
                        mCallbacks.get(i).enterStageSplitFromRunningApp((Boolean) msg.obj);
                    }
                    break;
                case MSG_SHOW_MEDIA_OUTPUT_SWITCHER:
                    args = (SomeArgs) msg.obj;
                    String clientPackageName = (String) args.arg1;
                    for (int i = 0; i < mCallbacks.size(); i++) {
                        mCallbacks.get(i).showMediaOutputSwitcher(clientPackageName);
                    }
                    break;
            }
        }
    }
Loading