diff options
| author | 2023-01-09 13:31:42 +0000 | |
|---|---|---|
| committer | 2023-01-16 14:00:35 +0000 | |
| commit | f2373017c85b681c20a755ba98078c23f6d732dd (patch) | |
| tree | 1e22378a16f49a6256f0279217b233eada4a9820 | |
| parent | f5bf900a9673abef4e8ecf7b68fc10e1190193c9 (diff) | |
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
7 files changed, 136 insertions, 0 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 017bf3f3dd6c..04fc4a6fd81d 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 8012dea643fb..8e9992fdd296 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 20ae64cf5985..f34489c781ea 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -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") } diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java new file mode 100644 index 000000000000..e35575bfc184 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputSwitcherDialogUI.java @@ -0,0 +1,71 @@ +/* + * 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."); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 750d00466a8d..fb65fbf2cd1d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -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) { @@ -1262,6 +1270,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, @NonNull CharSequence appName, @@ -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; } } } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java index e7221c850da8..fde0b34c7836 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerInternal.java @@ -191,4 +191,12 @@ public interface StatusBarManagerInternal { * @see com.android.internal.statusbar.IStatusBar#enterStageSplitFromRunningApp */ void enterStageSplitFromRunningApp(boolean leftOrTop); + + /** + * Shows the media output switcher dialog. + * + * @param packageName of the session for which the output switcher is shown. + * @see com.android.internal.statusbar.IStatusBar#showMediaOutputSwitcher + */ + void showMediaOutputSwitcher(String packageName); } diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 45748e6ce76d..ab7292d49c7d 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -714,6 +714,16 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D } catch (RemoteException ex) { } } } + + @Override + public void showMediaOutputSwitcher(String packageName) { + if (mBar != null) { + try { + mBar.showMediaOutputSwitcher(packageName); + } catch (RemoteException ex) { + } + } + } }; private final GlobalActionsProvider mGlobalActionsProvider = new GlobalActionsProvider() { |