1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.media.dialog; 18 19 import android.content.Context; 20 import android.os.Bundle; 21 import android.util.FeatureFlagUtils; 22 import android.view.View; 23 import android.view.WindowManager; 24 25 import androidx.core.graphics.drawable.IconCompat; 26 27 import com.android.internal.annotations.VisibleForTesting; 28 import com.android.internal.logging.UiEvent; 29 import com.android.internal.logging.UiEventLogger; 30 import com.android.systemui.R; 31 import com.android.systemui.animation.DialogLaunchAnimator; 32 import com.android.systemui.broadcast.BroadcastSender; 33 import com.android.systemui.dagger.SysUISingleton; 34 35 /** 36 * Dialog for media output transferring. 37 */ 38 @SysUISingleton 39 public class MediaOutputDialog extends MediaOutputBaseDialog { 40 private final DialogLaunchAnimator mDialogLaunchAnimator; 41 private final UiEventLogger mUiEventLogger; 42 MediaOutputDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender, MediaOutputController mediaOutputController, DialogLaunchAnimator dialogLaunchAnimator, UiEventLogger uiEventLogger)43 MediaOutputDialog(Context context, boolean aboveStatusbar, BroadcastSender broadcastSender, 44 MediaOutputController mediaOutputController, DialogLaunchAnimator dialogLaunchAnimator, 45 UiEventLogger uiEventLogger) { 46 super(context, broadcastSender, mediaOutputController); 47 mDialogLaunchAnimator = dialogLaunchAnimator; 48 mUiEventLogger = uiEventLogger; 49 mAdapter = new MediaOutputAdapter(mMediaOutputController); 50 if (!aboveStatusbar) { 51 getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); 52 } 53 } 54 55 @Override onCreate(Bundle savedInstanceState)56 public void onCreate(Bundle savedInstanceState) { 57 super.onCreate(savedInstanceState); 58 mUiEventLogger.log(MediaOutputEvent.MEDIA_OUTPUT_DIALOG_SHOW); 59 } 60 61 @Override getHeaderIconRes()62 int getHeaderIconRes() { 63 return 0; 64 } 65 66 @Override getHeaderIcon()67 IconCompat getHeaderIcon() { 68 return mMediaOutputController.getHeaderIcon(); 69 } 70 71 @Override getHeaderIconSize()72 int getHeaderIconSize() { 73 return mContext.getResources().getDimensionPixelSize( 74 R.dimen.media_output_dialog_header_album_icon_size); 75 } 76 77 @Override getHeaderText()78 CharSequence getHeaderText() { 79 return mMediaOutputController.getHeaderTitle(); 80 } 81 82 @Override getHeaderSubtitle()83 CharSequence getHeaderSubtitle() { 84 return mMediaOutputController.getHeaderSubTitle(); 85 } 86 87 @Override getAppSourceIcon()88 IconCompat getAppSourceIcon() { 89 return mMediaOutputController.getNotificationSmallIcon(); 90 } 91 92 @Override getStopButtonVisibility()93 int getStopButtonVisibility() { 94 boolean isActiveRemoteDevice = false; 95 if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) { 96 isActiveRemoteDevice = mMediaOutputController.isActiveRemoteDevice( 97 mMediaOutputController.getCurrentConnectedMediaDevice()); 98 } 99 boolean showBroadcastButton = isBroadcastSupported() && mMediaOutputController.isPlaying(); 100 101 return (isActiveRemoteDevice || showBroadcastButton) ? View.VISIBLE : View.GONE; 102 } 103 104 @Override isBroadcastSupported()105 public boolean isBroadcastSupported() { 106 boolean isBluetoothLeDevice = false; 107 boolean isBroadcastEnabled = false; 108 if (FeatureFlagUtils.isEnabled(mContext, 109 FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)) { 110 if (mMediaOutputController.getCurrentConnectedMediaDevice() != null) { 111 isBluetoothLeDevice = mMediaOutputController.isBluetoothLeDevice( 112 mMediaOutputController.getCurrentConnectedMediaDevice()); 113 // if broadcast is active, broadcast should be considered as supported 114 // there could be a valid case that broadcast is ongoing 115 // without active LEA device connected 116 isBroadcastEnabled = mMediaOutputController.isBluetoothLeBroadcastEnabled(); 117 } 118 } else { 119 // To decouple LE Audio Broadcast and Unicast, it always displays the button when there 120 // is no LE Audio device connected to the phone 121 isBluetoothLeDevice = true; 122 } 123 124 return mMediaOutputController.isBroadcastSupported() 125 && (isBluetoothLeDevice || isBroadcastEnabled); 126 } 127 128 @Override getStopButtonText()129 public CharSequence getStopButtonText() { 130 int resId = R.string.media_output_dialog_button_stop_casting; 131 if (isBroadcastSupported() && mMediaOutputController.isPlaying() 132 && !mMediaOutputController.isBluetoothLeBroadcastEnabled()) { 133 resId = R.string.media_output_broadcast; 134 } 135 return mContext.getText(resId); 136 } 137 138 @Override onStopButtonClick()139 public void onStopButtonClick() { 140 if (isBroadcastSupported() && mMediaOutputController.isPlaying()) { 141 if (!mMediaOutputController.isBluetoothLeBroadcastEnabled()) { 142 if (startLeBroadcastDialogForFirstTime()) { 143 return; 144 } 145 startLeBroadcast(); 146 } else { 147 stopLeBroadcast(); 148 } 149 } else { 150 mMediaOutputController.releaseSession(); 151 mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations(); 152 dismiss(); 153 } 154 } 155 156 @Override getBroadcastIconVisibility()157 public int getBroadcastIconVisibility() { 158 return (isBroadcastSupported() && mMediaOutputController.isBluetoothLeBroadcastEnabled()) 159 ? View.VISIBLE : View.GONE; 160 } 161 162 @Override onBroadcastIconClick()163 public void onBroadcastIconClick() { 164 startLeBroadcastDialog(); 165 } 166 167 @VisibleForTesting 168 public enum MediaOutputEvent implements UiEventLogger.UiEventEnum { 169 @UiEvent(doc = "The MediaOutput dialog became visible on the screen.") 170 MEDIA_OUTPUT_DIALOG_SHOW(655); 171 172 private final int mId; 173 MediaOutputEvent(int id)174 MediaOutputEvent(int id) { 175 mId = id; 176 } 177 178 @Override getId()179 public int getId() { 180 return mId; 181 } 182 } 183 } 184