1 /* <lambda>null2 * Copyright 2023 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.window.layout.adapter.extensions 18 19 import android.content.Context 20 import androidx.annotation.GuardedBy 21 import androidx.core.util.Consumer 22 import androidx.window.extensions.layout.WindowLayoutInfo as OEMWindowLayoutInfo 23 import androidx.window.layout.WindowLayoutInfo 24 import java.util.concurrent.locks.ReentrantLock 25 import kotlin.concurrent.withLock 26 27 /** A [Consumer] that handles multicasting to multiple [Consumer]s downstream. */ 28 internal class MulticastConsumer(private val context: Context) : Consumer<OEMWindowLayoutInfo> { 29 private val globalLock = ReentrantLock() 30 31 @GuardedBy("globalLock") private var lastKnownValue: WindowLayoutInfo? = null 32 @GuardedBy("globalLock") 33 private val registeredListeners = mutableSetOf<Consumer<WindowLayoutInfo>>() 34 35 override fun accept(value: OEMWindowLayoutInfo) { 36 globalLock.withLock { 37 val newValue = ExtensionsWindowLayoutInfoAdapter.translate(context, value) 38 lastKnownValue = newValue 39 registeredListeners.forEach { consumer -> consumer.accept(newValue) } 40 } 41 } 42 43 fun addListener(listener: Consumer<WindowLayoutInfo>) { 44 globalLock.withLock { 45 lastKnownValue?.let { value -> listener.accept(value) } 46 registeredListeners.add(listener) 47 } 48 } 49 50 fun removeListener(listener: Consumer<WindowLayoutInfo>) { 51 globalLock.withLock { registeredListeners.remove(listener) } 52 } 53 54 fun isEmpty(): Boolean { 55 return registeredListeners.isEmpty() 56 } 57 } 58