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 /** Called when the recommendation card should no longer be visible in QQS or lockscreen */ 72 fun setRecommendationInactive(key: String) 73 74 /** Invoked when notification is removed. */ 75 fun onNotificationRemoved(key: String) 76 77 fun setMediaResumptionEnabled(isEnabled: Boolean) 78 79 /** Invoked when the user has dismissed the media carousel */ 80 fun onSwipeToDismiss() 81 82 /** Are there any media notifications active, including the recommendations? */ 83 fun hasActiveMediaOrRecommendation(): Boolean 84 85 /** Are there any media entries we should display, including the recommendations? */ 86 fun hasAnyMediaOrRecommendation(): Boolean 87 88 /** Are there any resume media notifications active, excluding the recommendations? */ 89 fun hasActiveMedia(): Boolean 90 91 /** Are there any resume media notifications active, excluding the recommendations? */ 92 fun hasAnyMedia(): Boolean 93 94 /** Is recommendation card active? */ 95 fun isRecommendationActive(): Boolean 96 97 // Uses [MediaDataProcessor.Listener] in order to link the new logic code with UI layer. 98 interface Listener : MediaDataProcessor.Listener { 99 100 /** 101 * Called whenever there's new MediaData Loaded for the consumption in views. 102 * 103 * oldKey is provided to check whether the view has changed keys, which can happen when a 104 * player has gone from resume state (key is package name) to active state (key is 105 * notification key) or vice versa. 106 * 107 * @param immediately indicates should apply the UI changes immediately, otherwise wait 108 * until the next refresh-round before UI becomes visible. True by default to take in 109 * place immediately. 110 * @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI 111 * displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace 112 * signal. 113 * @param isSsReactivated indicates resume media card is reactivated by Smartspace 114 * recommendation signal 115 */ 116 override fun onMediaDataLoaded( 117 key: String, 118 oldKey: String?, 119 data: MediaData, 120 immediately: Boolean, 121 receivedSmartspaceCardLatency: Int, 122 isSsReactivated: Boolean, 123 ) {} 124 125 /** 126 * Called whenever there's new Smartspace media data loaded. 127 * 128 * @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true, 129 * it will be prioritized as the first card. Otherwise, it will show up as the last card 130 * as default. 131 */ 132 override fun onSmartspaceMediaDataLoaded( 133 key: String, 134 data: SmartspaceMediaData, 135 shouldPrioritize: Boolean, 136 ) {} 137 138 /** Called whenever a previously existing Media notification was removed. */ 139 override fun onMediaDataRemoved(key: String, userInitiated: Boolean) {} 140 141 /** 142 * Called whenever a previously existing Smartspace media data was removed. 143 * 144 * @param immediately indicates should apply the UI changes immediately, otherwise wait 145 * until the next refresh-round before UI becomes visible. True by default to take in 146 * place immediately. 147 */ 148 override fun onSmartspaceMediaDataRemoved(key: String, immediately: Boolean) {} 149 } 150 151 companion object { 152 153 @JvmStatic isMediaNotificationnull154 fun isMediaNotification(sbn: StatusBarNotification): Boolean { 155 return sbn.notification.isMediaNotification() 156 } 157 } 158 } 159