1 /* 2 * Copyright (C) 2024 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.controls.domain.pipeline 18 19 import android.app.PendingIntent 20 import android.media.MediaDescription 21 import android.media.session.MediaSession 22 import android.service.notification.StatusBarNotification 23 import com.android.systemui.media.controls.shared.model.MediaData 24 import com.android.systemui.media.controls.shared.model.SmartspaceMediaData 25 26 /** Facilitates management and loading of Media Data, ready for binding. */ 27 interface MediaDataManager { 28 29 /** Add a listener for changes in this class */ addListenernull30 fun addListener(listener: Listener) {} 31 32 /** Remove a listener for changes in this class */ removeListenernull33 fun removeListener(listener: Listener) {} 34 35 /** 36 * Called whenever the player has been paused or stopped for a while, or swiped from QQS. This 37 * will make the player not active anymore, hiding it from QQS and Keyguard. 38 * 39 * @see MediaData.active 40 */ setInactivenull41 fun setInactive(key: String, timedOut: Boolean, forceUpdate: Boolean = false) 42 43 /** Invoked when media notification is added. */ 44 fun onNotificationAdded(key: String, sbn: StatusBarNotification) 45 46 fun destroy() 47 48 /** Sets resume action. */ 49 fun setResumeAction(key: String, action: Runnable?) 50 51 /** Adds resume media data. */ 52 fun addResumptionControls( 53 userId: Int, 54 desc: MediaDescription, 55 action: Runnable, 56 token: MediaSession.Token, 57 appName: String, 58 appIntent: PendingIntent, 59 packageName: String, 60 ) 61 62 /** Dismiss a media entry. Returns false if the key was not found. */ 63 fun dismissMediaData(key: String, delay: Long, userInitiated: Boolean): Boolean 64 65 /** 66 * Called whenever the recommendation has been expired or removed by the user. This will remove 67 * the recommendation card entirely from the carousel. 68 */ 69 fun dismissSmartspaceRecommendation(key: String, delay: Long) 70 71 /** Invoked when notification is removed. */ 72 fun onNotificationRemoved(key: String) 73 74 fun setMediaResumptionEnabled(isEnabled: Boolean) 75 76 /** Invoked when the user has dismissed the media carousel */ 77 fun onSwipeToDismiss() 78 79 /** Are there any media notifications active, including the recommendations? */ 80 fun hasActiveMediaOrRecommendation(): Boolean 81 82 /** Are there any media entries we should display, including the recommendations? */ 83 fun hasAnyMediaOrRecommendation(): Boolean 84 85 /** Are there any resume media notifications active, excluding the recommendations? */ 86 fun hasActiveMedia(): Boolean 87 88 /** Are there any resume media notifications active, excluding the recommendations? */ 89 fun hasAnyMedia(): Boolean 90 91 /** Is recommendation card active? */ 92 fun isRecommendationActive(): Boolean 93 94 // Uses [MediaDataProcessor.Listener] in order to link the new logic code with UI layer. 95 interface Listener : MediaDataProcessor.Listener { 96 97 /** 98 * Called whenever there's new MediaData Loaded for the consumption in views. 99 * 100 * oldKey is provided to check whether the view has changed keys, which can happen when a 101 * player has gone from resume state (key is package name) to active state (key is 102 * notification key) or vice versa. 103 * 104 * @param immediately indicates should apply the UI changes immediately, otherwise wait 105 * until the next refresh-round before UI becomes visible. True by default to take in 106 * place immediately. 107 * @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI 108 * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace 109 * signal. 110 * @param isSsReactivated indicates resume media card is reactivated by Smartspace 111 * recommendation signal 112 */ 113 override fun onMediaDataLoaded( 114 key: String, 115 oldKey: String?, 116 data: MediaData, 117 immediately: Boolean, 118 receivedSmartspaceCardLatency: Int, 119 isSsReactivated: Boolean, 120 ) {} 121 122 /** 123 * Called whenever there's new Smartspace media data loaded. 124 * 125 * @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true, 126 * it will be prioritized as the first card. Otherwise, it will show up as the last card 127 * as default. 128 */ 129 override fun onSmartspaceMediaDataLoaded( 130 key: String, 131 data: SmartspaceMediaData, 132 shouldPrioritize: Boolean, 133 ) {} 134 135 /** Called whenever a previously existing Media notification was removed. */ 136 override fun onMediaDataRemoved(key: String, userInitiated: Boolean) {} 137 138 /** 139 * Called whenever a previously existing Smartspace media data was removed. 140 * 141 * @param immediately indicates should apply the UI changes immediately, otherwise wait 142 * until the next refresh-round before UI becomes visible. True by default to take in 143 * place immediately. 144 */ 145 override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {} 146 147 /** 148 * Called whenever the current active media notification changes. Should only be used if 149 * [SceneContainerFlag] is disabled 150 */ 151 override fun onCurrentActiveMediaChanged(key: String?, data: MediaData?) {} 152 } 153 154 companion object { 155 156 @JvmStatic isMediaNotificationnull157 fun isMediaNotification(sbn: StatusBarNotification): Boolean { 158 return sbn.notification.isMediaNotification() 159 } 160 } 161 } 162