1 /* <lambda>null2 * Copyright (C) 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 package com.android.cts.mockime 17 18 import android.os.Bundle 19 import android.os.RemoteCallback 20 import java.util.function.Consumer 21 import kotlinx.atomicfu.atomic 22 23 class SessionChannel(private var mEstablishedCallback: Runnable) : AutoCloseable { 24 private val listeners = mutableListOf<Consumer<Bundle>>() 25 private val remote = atomic<RemoteCallback?>(null) 26 private var local: RemoteCallback? = RemoteCallback { bundle -> 27 checkNotNull(bundle) 28 if (bundle.containsKey(ESTABLISH_KEY)) { 29 val remote = bundle.getParcelable(ESTABLISH_KEY, RemoteCallback::class.java)!! 30 check(this.remote.getAndSet(remote) == null) { 31 "already initialized" 32 } 33 mEstablishedCallback.run() 34 mEstablishedCallback = Runnable {} 35 } else { 36 listeners.forEach { listener -> 37 listener.accept(bundle) 38 } 39 } 40 } 41 42 constructor(transport: RemoteCallback) : this({}) { 43 this.remote.value = transport 44 send(Bundle().apply { 45 putParcelable(ESTABLISH_KEY, takeTransport()) 46 }) 47 } 48 49 fun takeTransport(): RemoteCallback { 50 val taken = checkNotNull(local) { "Can only take transport once" } 51 local = null 52 return taken 53 } 54 55 fun send(bundle: Bundle): Boolean { 56 val remote = remote.value ?: run { 57 return false 58 } 59 remote.sendResult(bundle) 60 return true 61 } 62 63 fun registerListener(listener: Consumer<Bundle>) { 64 listeners.add(listener) 65 } 66 67 fun unregisterListener(listener: Consumer<Bundle>) { 68 listeners.remove(listener) 69 } 70 71 override fun close() { 72 remote.value = null 73 listeners.clear() 74 } 75 76 companion object { 77 val ESTABLISH_KEY = SessionChannel::class.qualifiedName 78 } 79 } 80