1 /* 2 * Copyright 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 androidx.core.telecom.extensions 18 19 import android.net.Uri 20 import androidx.core.telecom.CallControlScope 21 import androidx.core.telecom.util.ExperimentalAppActions 22 23 /** 24 * The scope used to initialize extensions on a call as well as manage initialized extensions 25 * associated with the call once the call has been set up. 26 * 27 * Extensions contain state and optional actions that are used to support additional features on a 28 * call, such as information about the participants in the call. 29 * 30 * Supported Extensions: 31 * - The ability to describe meeting participant information as well as actions on those 32 * participants using [addParticipantExtension] 33 * 34 * For example, to add participant support, the participant extension can be created during 35 * initialization and then used as part of [onCall] to update participant state and listen to action 36 * requests from remote surfaces: 37 * ``` 38 * scope.launch { 39 * mCallsManager.addCallWithExtensions(attributes, 40 * onAnswerLambda, 41 * onDisconnectLambda, 42 * onSetActiveLambda, 43 * onSetInactiveLambda) { 44 * // Initialize extensions ... 45 * // Example: add participants support & associated actions 46 * val participantExtension = addParticipantExtension(initialParticipants) 47 * val raiseHandState = participantExtension.addRaiseHandSupport( 48 * initialRaisedHands) { onHandRaisedStateChanged -> 49 * // handle raised hand state changed 50 * } 51 * participantExtension.addKickParticipantSupport { 52 * participant -> 53 * // handle kicking the requested participant 54 * } 55 * // Call has been set up, perform in-call actions 56 * onCall { 57 * // Example: collect call state updates 58 * callStateFlow.onEach { newState -> 59 * // handle call state updates 60 * }.launchIn(this) 61 * // update participant extensions 62 * participantsFlow.onEach { newParticipants -> 63 * participantExtension.updateParticipants(newParticipants) 64 * }.launchIn(this) 65 * raisedHandsFlow.onEach { newRaisedHands -> 66 * raiseHandState.updateRaisedHands(newRaisedHands) 67 * }.launchIn(this) 68 * } 69 * } 70 * } 71 * } 72 * ``` 73 */ 74 @ExperimentalAppActions 75 public interface ExtensionInitializationScope { 76 77 /** 78 * User provided callback implementation that is run when the call is ready using the provided 79 * [CallControlScope]. 80 * 81 * @param onCall callback invoked when the call has been notified to the framework and the call 82 * is ready 83 */ onCallnull84 public fun onCall(onCall: suspend CallControlScope.() -> Unit) 85 86 /** 87 * Adds the participant extension to a call, which provides the ability for this application to 88 * specify participant related information, which will be shared with remote surfaces that 89 * support displaying that information (automotive, watch, etc...). 90 * 91 * @param initialParticipants The initial [List] of [Participant]s in the call. Participants are 92 * displayed on the remote screen according to their order within the participants list, 93 * starting with the first element. Duplicate participants are removed. If the same 94 * participant is added to the list more than once, **only the first occurrence of that 95 * participant** will be retained in the list; subsequent duplicates are dropped. 96 * @param initialActiveParticipant The initial [Participant] that is active in the call or 97 * `null` if there is no active participant. 98 * @return The interface used by this application to further update the participant extension 99 * state to remote surfaces 100 */ 101 public fun addParticipantExtension( 102 initialParticipants: List<Participant> = emptyList(), 103 initialActiveParticipant: Participant? = null 104 ): ParticipantExtension 105 106 /** 107 * Adds the local call silence extension to a call, which provides the ability for this 108 * application to signal to the local call silence state to other surfaces (e.g. Android Auto) 109 * 110 * Local Call Silence means that the call should be silenced at the application layer (local 111 * silence) instead of the hardware layer (global silence). Using a local call silence over 112 * global silence is advantageous when the application wants to still receive the audio input 113 * data while not transmitting audio input data to remote users. 114 * 115 * @param initialCallSilenceState The initial call silence value at the start of the call. True, 116 * signals silence the user and do not transmit audio data to the remote users. False signals 117 * the mic is transmitting audio data at the application layer. 118 * @param onLocalSilenceUpdate This is called when the user has requested to change their 119 * silence state on a remote surface. If true, this user has requested to silence the 120 * microphone. If false, this user has unsilenced the microphone. This operation should not 121 * return until the request has been processed. 122 * @return The interface used by this application to further update the local call silence 123 * extension state to remote surfaces 124 */ 125 public fun addLocalCallSilenceExtension( 126 initialCallSilenceState: Boolean, 127 onLocalSilenceUpdate: (suspend (Boolean) -> Unit), 128 ): LocalCallSilenceExtension 129 130 /** 131 * Adds the call icon extension to a call, which allows the application to specify a custom icon 132 * to be displayed on remote surfaces (e.g., automotive displays, smartwatches) during an active 133 * call. This provides a way to visually represent the call with a specific app, service, or 134 * context. 135 * 136 * @param initialCallIconUri The initial [Uri] of the icon to be displayed. This URI should 137 * point to a valid image resource that can be loaded and displayed by remote surfaces. 138 * Consider using a Content Provider URI for accessing resources within your application. 139 * @return The interface used by this application to further update the call icon extension 140 * state to remote surfaces. This allows dynamically changing the icon during the call. 141 */ 142 public fun addCallIconExtension(initialCallIconUri: Uri): CallIconExtension 143 } 144