diff --git a/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/MediaSessionHandlerMessengerService.kt b/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/MediaSessionHandlerMessengerService.kt index b56be64..e1ba0fb 100644 --- a/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/MediaSessionHandlerMessengerService.kt +++ b/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/MediaSessionHandlerMessengerService.kt @@ -87,343 +87,376 @@ class MediaSessionHandlerMessengerService() : Service() { else -> super.handleMessage(msg) } } + } - private fun registerClient(msg: Message) { - clientsSessionData[msg.sendingUid] = ClientSessionModel(msg.replyTo) - } + private fun registerClient(msg: Message) { + clientsSessionData[msg.sendingUid] = ClientSessionModel(msg.replyTo) + } - private fun unregisterClient(msg: Message) { - clientsSessionData.remove(msg.sendingUid) - } + private fun unregisterClient(msg: Message) { + clientsSessionData.remove(msg.sendingUid) + } - private fun handleStatusMessage(msg: Message) { - val sendingUid = msg.sendingUid - val bundle: Bundle = msg.data as Bundle - val state: String = bundle.getString("playbackState", "") - Log.i(TAG, "[ConsumptionReporting] playbackState updated【$state】") - Toast.makeText( - applicationContext, - "Media Session Handler Service received state message: $state", - Toast.LENGTH_SHORT - ).show() - - when (state) { - PlayerStates.ENDED -> { - stopConsumptionReportingTimer(sendingUid) - } + private fun handleStatusMessage(msg: Message) { + val sendingUid = msg.sendingUid + val bundle: Bundle = msg.data as Bundle + val state: String = bundle.getString("playbackState", "") + Log.i(TAG, "[ConsumptionReporting] playbackState updated【$state】") + Toast.makeText( + applicationContext, + "Media Session Handler Service received state message: $state", + Toast.LENGTH_SHORT + ).show() + + when (state) { + PlayerStates.ENDED -> { + stopConsumptionReportingTimer(sendingUid) + } - PlayerStates.READY -> { - initializeNewPlaybackSession(sendingUid) - } + PlayerStates.READY -> { + initializeNewPlaybackSession(sendingUid) } } + } - private fun initializeNewPlaybackSession(clientId: Int) { - if (clientsSessionData[clientId] != null && clientsSessionData[clientId]?.initializedSession == false) { + private fun initializeNewPlaybackSession(clientId: Int) { + if (clientsSessionData[clientId] != null && clientsSessionData[clientId]?.initializedSession == false) { - // Set AF endpoint for consumption reporting - setConsumptionReportingEndpoint(clientId) + // Start consumption reporting + initializeConsumptionReportingTimer(clientId, 0) - // Start consumption reporting - initializeConsumptionReportingTimer(clientId, 0) + clientsSessionData[clientId]?.initializedSession = true + } + } - clientsSessionData[clientId]?.initializedSession = true - } + private fun initializeConsumptionReportingTimer(clientId: Int, delay: Long? = null) { + setConsumptionReportingEndpoint(clientId) + // Do not start the consumption reporting timer if we dont have an endpoint + if (clientsSessionData[clientId]?.consumptionReportingApi == null) { + return } - private fun handleStartPlaybackByServiceListEntryMessage(msg: Message) { - val bundle: Bundle = msg.data - bundle.classLoader = ServiceListEntry::class.java.classLoader - val serviceListEntry: ServiceListEntry? = bundle.getParcelable("serviceListEntry") - val responseMessenger: Messenger = msg.replyTo - val sendingUid = msg.sendingUid; + val clientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration? = + clientsSessionData[clientId]?.serviceAccessInformation?.clientConsumptionReportingConfiguration - finalizeCurrentPlaybackSession(sendingUid) + if (clientConsumptionReportingConfiguration?.reportingInterval != null && + clientConsumptionReportingConfiguration.reportingInterval!! > 0 && + shouldReportAccordingToSamplePercentage(clientConsumptionReportingConfiguration.samplePercentage) + ) { + startConsumptionReportingTimer(clientId, delay) + } + } - val provisioningSessionId: String = serviceListEntry!!.provisioningSessionId - val call: Call? = - clientsSessionData[msg.sendingUid]?.serviceAccessInformationApi?.fetchServiceAccessInformation( - provisioningSessionId, + private fun handleStartPlaybackByServiceListEntryMessage(msg: Message) { + val bundle: Bundle = msg.data + bundle.classLoader = ServiceListEntry::class.java.classLoader + val serviceListEntry: ServiceListEntry? = bundle.getParcelable("serviceListEntry") + val responseMessenger: Messenger = msg.replyTo + val sendingUid = msg.sendingUid; + + resetClientSessionData(sendingUid) + + val provisioningSessionId: String = serviceListEntry!!.provisioningSessionId + val call: Call? = + clientsSessionData[msg.sendingUid]?.serviceAccessInformationApi?.fetchServiceAccessInformation( + provisioningSessionId, + null, + null + ) + call?.enqueue(object : retrofit2.Callback { + override fun onResponse( + call: Call, + response: Response + ) { + + val resource = + handleServiceAccessResponse(response, sendingUid, provisioningSessionId) + + // Trigger the playback by providing all available entry points + val msgResponse: Message = Message.obtain( null, - null + SessionHandlerMessageTypes.SESSION_HANDLER_TRIGGERS_PLAYBACK ) - call?.enqueue(object : retrofit2.Callback { - override fun onResponse( - call: Call, - response: Response - ) { - - val resource = - handleServiceAccessResponse(response, sendingUid, provisioningSessionId) - - // Trigger the playback by providing all available entry points - val msgResponse: Message = Message.obtain( - null, - SessionHandlerMessageTypes.SESSION_HANDLER_TRIGGERS_PLAYBACK - ) - var finalEntryPoints: ArrayList? = serviceListEntry.entryPoints - if (resource != null && (finalEntryPoints == null || finalEntryPoints.size == 0)) { - finalEntryPoints = - resource.streamingAccess.entryPoints - } - - val responseBundle = Bundle() - if (finalEntryPoints != null && finalEntryPoints.size > 0) { - val playbackConsumptionReportingConfiguration = - PlaybackConsumptionReportingConfiguration() - if (resource?.clientConsumptionReportingConfiguration != null) { - playbackConsumptionReportingConfiguration.accessReporting = - resource.clientConsumptionReportingConfiguration!!.accessReporting - playbackConsumptionReportingConfiguration.locationReporting = - resource.clientConsumptionReportingConfiguration!!.locationReporting - } - val playbackRequest = - PlaybackRequest( - finalEntryPoints, - playbackConsumptionReportingConfiguration - ) - responseBundle.putParcelable("playbackRequest", playbackRequest) - msgResponse.data = responseBundle - responseMessenger.send(msgResponse) - } + var finalEntryPoints: ArrayList? = serviceListEntry.entryPoints + if (resource != null && (finalEntryPoints == null || finalEntryPoints.size == 0)) { + finalEntryPoints = + resource.streamingAccess.entryPoints } - override fun onFailure(call: Call, t: Throwable) { - Log.i(TAG, "debug onFailure") - call.cancel() + val responseBundle = Bundle() + if (finalEntryPoints != null && finalEntryPoints.size > 0) { + val playbackConsumptionReportingConfiguration = + PlaybackConsumptionReportingConfiguration() + if (resource?.clientConsumptionReportingConfiguration != null) { + playbackConsumptionReportingConfiguration.accessReporting = + resource.clientConsumptionReportingConfiguration!!.accessReporting + playbackConsumptionReportingConfiguration.locationReporting = + resource.clientConsumptionReportingConfiguration!!.locationReporting + } + val playbackRequest = + PlaybackRequest( + finalEntryPoints, + playbackConsumptionReportingConfiguration + ) + responseBundle.putParcelable("playbackRequest", playbackRequest) + msgResponse.data = responseBundle + responseMessenger.send(msgResponse) } - }) - } - - private fun finalizeCurrentPlaybackSession(clientId: Int) { - if (clientsSessionData[clientId] != null) { - Log.i(TAG, "Resetting information for client $clientId") - clientsSessionData[clientId]?.serviceAccessInformation = null - clientsSessionData[clientId]?.serviceAccessInformationRequestTimer?.cancel() - clientsSessionData[clientId]?.serviceAccessInformationRequestTimer = null - clientsSessionData[clientId]?.serviceAccessInformationResponseHeaders = null - clientsSessionData[clientId]?.initializedSession = false - stopConsumptionReportingTimer(clientId) } - } - /** - * Starts the timer task to re-request and saves the current state of the Service Access Information - * - * @param response - * @param sendingUid - * @param provisioningSessionId - * @return - */ - private fun handleServiceAccessResponse( - response: Response, - sendingUid: Int, - provisioningSessionId: String - ): ServiceAccessInformation? { - val headers = response.headers() - // TODO Verify that this is not copy by reference and objects are the same - var previousServiceAccessInformation: ServiceAccessInformation? = clientsSessionData[sendingUid]?.serviceAccessInformation - - // Save the ServiceAccessInformation if it has changed - val resource: ServiceAccessInformation? = response.body() - if (resource != null && response.code() != 304 && utils.hasResponseChanged( - headers, - clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders - ) - ) { - clientsSessionData[sendingUid]?.serviceAccessInformation = resource + override fun onFailure(call: Call, t: Throwable) { + Log.i(TAG, "debug onFailure") + call.cancel() } + }) + } - handleConsumptionReportingChanges( - previousServiceAccessInformation.clientConsumptionReportingConfiguration, - clientsSessionData[sendingUid]?.serviceAccessInformation?.clientConsumptionReportingConfiguration, - sendingUid - ) - + private fun resetClientSessionData(clientId: Int) { + if (clientsSessionData[clientId] != null) { + Log.i(TAG, "Resetting information for client $clientId") + clientsSessionData[clientId]?.serviceAccessInformation = null + clientsSessionData[clientId]?.serviceAccessInformationRequestTimer?.cancel() + clientsSessionData[clientId]?.serviceAccessInformationRequestTimer = null + clientsSessionData[clientId]?.serviceAccessInformationResponseHeaders = null + clientsSessionData[clientId]?.initializedSession = false + clientsSessionData[clientId]?.consumptionReportingSelectedServerAddress = null + stopConsumptionReportingTimer(clientId) + } + } - // Start the re-requesting of the Service Access Information according to the max-age header - startServiceAccessInformationUpdateTimer( + /** + * Starts the timer task to re-request and saves the current state of the Service Access Information + * + * @param response + * @param sendingUid + * @param provisioningSessionId + * @return + */ + private fun handleServiceAccessResponse( + response: Response, + sendingUid: Int, + provisioningSessionId: String + ): ServiceAccessInformation? { + val headers = response.headers() + val previousServiceAccessInformation: ServiceAccessInformation? = + clientsSessionData[sendingUid]?.serviceAccessInformation + + // Save the ServiceAccessInformation if it has changed + val resource: ServiceAccessInformation? = response.body() + if (resource != null && response.code() != 304 && utils.hasResponseChanged( headers, - sendingUid, - provisioningSessionId + clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders ) + ) { + clientsSessionData[sendingUid]?.serviceAccessInformation = resource + + // handle changes of the SAI compared to the previous one + if (previousServiceAccessInformation != null) { + handleConsumptionReportingChanges( + previousServiceAccessInformation.clientConsumptionReportingConfiguration, + clientsSessionData[sendingUid]?.serviceAccessInformation?.clientConsumptionReportingConfiguration, + sendingUid + ) + } + } - // Save current headers - clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders = headers + // Start the re-requesting of the Service Access Information according to the max-age header + startServiceAccessInformationUpdateTimer( + headers, + sendingUid, + provisioningSessionId + ) - return clientsSessionData[sendingUid]?.serviceAccessInformation - } + // Save current headers + clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders = headers - /** - * - * - * - */ - private fun handleConsumptionReportingChanges( - currentClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration?, - updatedClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration?, - clientId: Int - ) { - // there was no clientConsumptionReporting yet + return clientsSessionData[sendingUid]?.serviceAccessInformation + } - // there is no clientConsumptionReporting anymore + /** + * Once the SAI is updated we need to react to changes in the consumption reporting configuration + */ + private fun handleConsumptionReportingChanges( + previousClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration?, + updatedClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration?, + clientId: Int + ) { + if (previousClientConsumptionReportingConfiguration != null && updatedClientConsumptionReportingConfiguration != null) { // location or access reporting has changed update the representation in the Media Stream Handler - if (currentClientConsumptionReportingConfiguration != null && updatedClientConsumptionReportingConfiguration != null) { - if (currentClientConsumptionReportingConfiguration.accessReporting != updatedClientConsumptionReportingConfiguration.accessReporting || currentClientConsumptionReportingConfiguration.locationReporting != updatedClientConsumptionReportingConfiguration.locationReporting) { - updatePlaybackConsumptionReportingConfiguration( - clientId, - updatedClientConsumptionReportingConfiguration - ) - } + if (previousClientConsumptionReportingConfiguration.accessReporting != updatedClientConsumptionReportingConfiguration.accessReporting || previousClientConsumptionReportingConfiguration.locationReporting != updatedClientConsumptionReportingConfiguration.locationReporting) { + updatePlaybackConsumptionReportingConfiguration( + clientId, + updatedClientConsumptionReportingConfiguration + ) + } - // if sample percentage is set to 0 stop consumption reporting - if (updatedClientConsumptionReportingConfiguration.reportingInterval!! <= 0) { - stopConsumptionReportingTimer(clientId) - } + // if the list of endpoints is empty we stop reporting. No need to check anything else + if (updatedClientConsumptionReportingConfiguration.serverAddresses.isEmpty()) { + stopConsumptionReportingTimer(clientId) + clientsSessionData[clientId]?.consumptionReportingSelectedServerAddress = null + clientsSessionData[clientId]?.consumptionReportingApi = null + return + } - // if sample percentage is set to 100 start consumption reporting for all connected clients - if (updatedClientConsumptionReportingConfiguration.reportingInterval >= 100) { - startConsumptionReportingTimer(clientId) - } + // the currently used reporting endpoint has been removed from the list. Pick a new one + if (!updatedClientConsumptionReportingConfiguration.serverAddresses.contains( + clientsSessionData[clientId]?.consumptionReportingSelectedServerAddress + ) + ) { + setConsumptionReportingEndpoint(clientId) + } - // updates of the reporting interval are handled automatically when stopping / starting the timer + // if sample percentage is set to 0 or no server addresses are available stop consumption reporting + if (updatedClientConsumptionReportingConfiguration.samplePercentage!! <= 0) { + stopConsumptionReportingTimer(clientId) + } + // if sample percentage is set to 100 start consumption reporting + if (updatedClientConsumptionReportingConfiguration.samplePercentage!! >= 100) { + startConsumptionReportingTimer(clientId) } + + // updates of the reporting interval are handled automatically when stopping / starting the timer } + } - private fun updatePlaybackConsumptionReportingConfiguration( - clientId: Int, - updatedClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration - ) { - val msg: Message = Message.obtain( - null, - SessionHandlerMessageTypes.UPDATE_PLAYBACK_CONSUMPTION_REPORTING_CONFIGURATION - ) - val bundle = Bundle() - val locationReporting = - updatedClientConsumptionReportingConfiguration.locationReporting - val accessReporting = - updatedClientConsumptionReportingConfiguration.accessReporting - val consumptionReportingConfiguration = - PlaybackConsumptionReportingConfiguration(accessReporting, locationReporting) - bundle.putParcelable( - "playbackConsumptionReportingConfiguration", - consumptionReportingConfiguration + private fun updatePlaybackConsumptionReportingConfiguration( + clientId: Int, + updatedClientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration + ) { + val msg: Message = Message.obtain( + null, + SessionHandlerMessageTypes.UPDATE_PLAYBACK_CONSUMPTION_REPORTING_CONFIGURATION + ) + val bundle = Bundle() + val locationReporting = + updatedClientConsumptionReportingConfiguration.locationReporting + val accessReporting = + updatedClientConsumptionReportingConfiguration.accessReporting + val consumptionReportingConfiguration = + PlaybackConsumptionReportingConfiguration(accessReporting, locationReporting) + bundle.putParcelable( + "playbackConsumptionReportingConfiguration", + consumptionReportingConfiguration + ) + val messenger = clientsSessionData[clientId]?.messenger + msg.data = bundle + msg.replyTo = mMessenger + try { + Log.i( + TAG, + "Request consumption report for client $clientId" ) - val messenger = clientsSessionData[clientId]?.messenger - msg.data = bundle - msg.replyTo = mMessenger - try { - Log.i( - TAG, - "Request consumption report for client $clientId" - ) - messenger?.send(msg) - } catch (e: RemoteException) { - e.printStackTrace() - } + messenger?.send(msg) + } catch (e: RemoteException) { + e.printStackTrace() } + } - /** - * Starts the timer task to re-request the the Service Access Information - * - * @param headers - * @param sendingUid - * @param provisioningSessionId - */ - private fun startServiceAccessInformationUpdateTimer( - headers: Headers, - sendingUid: Int, - provisioningSessionId: String - ) { - val cacheControlHeader = headers.get("cache-control") ?: return - val cacheControlHeaderItems = cacheControlHeader.split(',') - val maxAgeHeader = cacheControlHeaderItems.filter { it.trim().startsWith("max-age=") } + /** + * Starts the timer task to re-request the the Service Access Information + * + * @param headers + * @param sendingUid + * @param provisioningSessionId + */ + private fun startServiceAccessInformationUpdateTimer( + headers: Headers, + sendingUid: Int, + provisioningSessionId: String + ) { + val cacheControlHeader = headers.get("cache-control") ?: return + val cacheControlHeaderItems = cacheControlHeader.split(',') + val maxAgeHeader = cacheControlHeaderItems.filter { it.trim().startsWith("max-age=") } - if (maxAgeHeader.isEmpty()) { - return - } + if (maxAgeHeader.isEmpty()) { + return + } + + val maxAgeValue = maxAgeHeader[0].trim().substring(8).toLong() + val timer = Timer() + clientsSessionData[sendingUid]?.serviceAccessInformationRequestTimer = timer - val maxAgeValue = maxAgeHeader[0].trim().substring(8).toLong() - val timer = Timer() - clientsSessionData[sendingUid]?.serviceAccessInformationRequestTimer = timer - - timer.schedule( - object : TimerTask() { - override fun run() { - val call: Call? = - clientsSessionData[sendingUid]?.serviceAccessInformationApi?.fetchServiceAccessInformation( - provisioningSessionId, - clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders?.get( - "etag" - ), - clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders?.get( - "last-modified" - ) + timer.schedule( + object : TimerTask() { + override fun run() { + val call: Call? = + clientsSessionData[sendingUid]?.serviceAccessInformationApi?.fetchServiceAccessInformation( + provisioningSessionId, + clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders?.get( + "etag" + ), + clientsSessionData[sendingUid]?.serviceAccessInformationResponseHeaders?.get( + "last-modified" + ) + ) + + call?.enqueue(object : retrofit2.Callback { + override fun onResponse( + call: Call, + response: Response + ) { + + handleServiceAccessResponse( + response, + sendingUid, + provisioningSessionId ) + } - call?.enqueue(object : retrofit2.Callback { - override fun onResponse( - call: Call, - response: Response - ) { - - handleServiceAccessResponse( - response, - sendingUid, - provisioningSessionId - ) - } - - override fun onFailure( - call: Call, - t: Throwable - ) { - call.cancel() - } - }) - } - }, - maxAgeValue * 1000 - ) + override fun onFailure( + call: Call, + t: Throwable + ) { + call.cancel() + } + }) + } + }, + maxAgeValue * 1000 + ) + } + + private fun setConsumptionReportingEndpoint(clientId: Int) { + clientsSessionData[clientId]?.consumptionReportingSelectedServerAddress = null + val clientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration? = + clientsSessionData[clientId]?.serviceAccessInformation?.clientConsumptionReportingConfiguration + + // Nothing to choose from + if (clientConsumptionReportingConfiguration?.serverAddresses?.isEmpty() == true) { + return } - private fun setConsumptionReportingEndpoint(clientId: Int) { - val clientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration? = - clientsSessionData[clientId]?.serviceAccessInformation?.clientConsumptionReportingConfiguration - // Select one of the servers to report the metrics to - var serverAddress = - clientConsumptionReportingConfiguration?.serverAddresses?.random() - // Add a "/" in the end if not present - serverAddress = serverAddress?.let { utils.addTrailingSlashIfNeeded(it) } - val retrofit = serverAddress?.let { retrofitBuilder.baseUrl(it).build() } - if (retrofit != null) { - clientsSessionData[clientId]?.consumptionReportingApi = - retrofit.create(ConsumptionReportingApi::class.java) - } + // Select one of the servers to report the metrics to + var serverAddress = + clientConsumptionReportingConfiguration?.serverAddresses?.random() + + // Add a "/" in the end if not present + serverAddress = serverAddress?.let { utils.addTrailingSlashIfNeeded(it) } + val retrofit = serverAddress?.let { retrofitBuilder.baseUrl(it).build() } + if (retrofit != null) { + clientsSessionData[clientId]?.consumptionReportingApi = + retrofit.create(ConsumptionReportingApi::class.java) + clientsSessionData[clientId]?.consumptionReportingSelectedServerAddress = + serverAddress } + } - private fun initializeConsumptionReportingTimer(clientId: Int, delay: Long? = null) { - val clientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration? = - clientsSessionData[clientId]?.serviceAccessInformation?.clientConsumptionReportingConfiguration + private fun startConsumptionReportingTimer(clientId: Int, delay: Long? = null) { - if (clientConsumptionReportingConfiguration?.reportingInterval != null && - clientConsumptionReportingConfiguration.reportingInterval!! > 0 && - shouldReportAccordingToSamplePercentage(clientConsumptionReportingConfiguration.samplePercentage) - ) { - startConsumptionReportingTimer(clientId, delay) - } + // Endpoint not set + if (clientsSessionData[clientId]?.consumptionReportingApi == null) { + setConsumptionReportingEndpoint(clientId) } - } + // Do nothing if the timer is already running + if (clientsSessionData[clientId]?.consumptionReportingTimer != null) { + return + } - private fun startConsumptionReportingTimer( - clientId: Int, - delay: Long? = null - ) { val clientConsumptionReportingConfiguration: ClientConsumptionReportingConfiguration = clientsSessionData[clientId]?.serviceAccessInformation?.clientConsumptionReportingConfiguration ?: return @@ -449,8 +482,10 @@ class MediaSessionHandlerMessengerService() : Service() { } private fun stopConsumptionReportingTimer(clientId: Int) { - clientsSessionData[clientId]?.consumptionReportingTimer?.cancel() - clientsSessionData[clientId]?.consumptionReportingTimer = null + if (clientsSessionData[clientId]?.consumptionReportingTimer != null) { + clientsSessionData[clientId]?.consumptionReportingTimer?.cancel() + clientsSessionData[clientId]?.consumptionReportingTimer = null + } } private fun shouldReportAccordingToSamplePercentage(samplePercentage: Float?): Boolean { @@ -503,7 +538,7 @@ class MediaSessionHandlerMessengerService() : Service() { bundle.getString("consumptionReport") val sendingUid = msg.sendingUid - if (clientsSessionData[sendingUid]?.serviceAccessInformation?.clientConsumptionReportingConfiguration == null) { + if (clientsSessionData[sendingUid]?.serviceAccessInformation?.clientConsumptionReportingConfiguration == null || clientsSessionData[sendingUid]?.consumptionReportingApi == null) { return } @@ -570,6 +605,4 @@ class MediaSessionHandlerMessengerService() : Service() { mMessenger = Messenger(IncomingHandler(this)) return mMessenger.binder } - - } \ No newline at end of file diff --git a/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/models/ClientSessionModel.kt b/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/models/ClientSessionModel.kt index 866feac..cdf2106 100644 --- a/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/models/ClientSessionModel.kt +++ b/app/src/main/java/com/fivegmag/a5gmsmediasessionhandler/models/ClientSessionModel.kt @@ -16,6 +16,7 @@ data class ClientSessionModel( var serviceAccessInformationRequestTimer: Timer? = null, var consumptionReportingApi: ConsumptionReportingApi? = null, var consumptionReportingTimer: Timer? = null, + var consumptionReportingSelectedServerAddress : String? = null, var playbackState: String = PlayerStates.UNKNOWN, var initializedSession: Boolean = false ) \ No newline at end of file