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.privacysandbox.ui.provider
18 
19 import android.content.res.Configuration
20 import android.os.Bundle
21 import androidx.privacysandbox.ui.core.SandboxedSdkViewUiInfo
22 import androidx.privacysandbox.ui.core.SandboxedUiAdapter
23 import androidx.privacysandbox.ui.core.SandboxedUiAdapterSignalOptions
24 import androidx.privacysandbox.ui.core.SessionObserver
25 import androidx.privacysandbox.ui.core.SessionObserverContext
26 import androidx.privacysandbox.ui.core.SessionObserverFactory
27 
28 /**
29  * An abstract class that implements [SandboxedUiAdapter] while abstracting away methods that do not
30  * need to be implemented by a UI provider.
31  *
32  * UI providers should use this class rather than implementing [SandboxedUiAdapter] directly.
33  */
34 abstract class AbstractSandboxedUiAdapter : SandboxedUiAdapter, SessionObserverFactoryRegistry {
35     private val registryProvider = SessionObserverFactoryRegistryProvider()
36 
37     private val delegateMap:
38         MutableMap<SessionObserverFactory, SessionObserverFactorySignalDelegate> =
39         mutableMapOf()
40 
41     final override val sessionObserverFactories: List<SessionObserverFactory>
42         get() = registryProvider.sessionObserverFactories
43 
addObserverFactorynull44     final override fun addObserverFactory(sessionObserverFactory: SessionObserverFactory) {
45         val delegateFactory = SessionObserverFactorySignalDelegate(sessionObserverFactory)
46         delegateMap.put(sessionObserverFactory, delegateFactory)
47         registryProvider.addObserverFactory(delegateFactory)
48     }
49 
removeObserverFactorynull50     final override fun removeObserverFactory(sessionObserverFactory: SessionObserverFactory) {
51         val proxy = delegateMap[sessionObserverFactory]
52         proxy?.let {
53             registryProvider.removeObserverFactory(proxy)
54             delegateMap.remove(sessionObserverFactory)
55         }
56     }
57 
58     /**
59      * A wrapper class of [SessionObserverFactory] that delegates calls to the underlying
60      * [SessionObserver]s based on the [signalOptions] specified by the factory.
61      */
62     private class SessionObserverFactorySignalDelegate(
63         val sessionObserverFactory: SessionObserverFactory
64     ) : SessionObserverFactory {
65         override val signalOptions: Set<String> = sessionObserverFactory.signalOptions
66 
createnull67         override fun create(): SessionObserver {
68             return SessionObserverSignalDelegate(sessionObserverFactory.create())
69         }
70 
71         private inner class SessionObserverSignalDelegate(val sessionObserver: SessionObserver) :
72             SessionObserver {
onSessionOpenednull73             override fun onSessionOpened(sessionObserverContext: SessionObserverContext) {
74                 sessionObserver.onSessionOpened(sessionObserverContext)
75             }
76 
onUiContainerChangednull77             override fun onUiContainerChanged(uiContainerInfo: Bundle) {
78                 SandboxedSdkViewUiInfo.pruneBundle(uiContainerInfo, signalOptions)
79                 if (
80                     signalOptions.contains(SandboxedUiAdapterSignalOptions.GEOMETRY) ||
81                         signalOptions.contains(SandboxedUiAdapterSignalOptions.OBSTRUCTIONS)
82                 ) {
83                     sessionObserver.onUiContainerChanged(uiContainerInfo)
84                 }
85             }
86 
onSessionClosednull87             override fun onSessionClosed() {
88                 sessionObserver.onSessionClosed()
89             }
90         }
91     }
92 
93     /**
94      * An abstract class that implements [SandboxedUiAdapter.Session] so that a UI provider does not
95      * need to implement the entire interface.
96      *
97      * UI providers should use this class rather than implementing [SandboxedUiAdapter.Session].
98      */
99     abstract class AbstractSession : SandboxedUiAdapter.Session {
100 
101         final override val signalOptions: Set<String>
102             get() = setOf()
103 
notifyZOrderChangednull104         override fun notifyZOrderChanged(isZOrderOnTop: Boolean) {}
105 
notifyResizednull106         override fun notifyResized(width: Int, height: Int) {}
107 
notifyConfigurationChangednull108         override fun notifyConfigurationChanged(configuration: Configuration) {}
109 
notifyUiChangednull110         override fun notifyUiChanged(uiContainerInfo: Bundle) {}
111 
notifySessionRenderednull112         override fun notifySessionRendered(supportedSignalOptions: Set<String>) {}
113 
closenull114         override fun close() {}
115     }
116 }
117