Merge "Connect weather complication view with DreamSmartspaceController" into tm-qpr-dev
This commit is contained in:
@@ -51,6 +51,7 @@ public interface RegisteredComplicationsModule {
|
|||||||
int DREAM_MEDIA_COMPLICATION_WEIGHT = 0;
|
int DREAM_MEDIA_COMPLICATION_WEIGHT = 0;
|
||||||
int DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT = 4;
|
int DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT = 4;
|
||||||
int DREAM_MEDIA_ENTRY_COMPLICATION_WEIGHT = 3;
|
int DREAM_MEDIA_ENTRY_COMPLICATION_WEIGHT = 3;
|
||||||
|
int DREAM_WEATHER_COMPLICATION_WEIGHT = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides layout parameters for the clock time complication.
|
* Provides layout parameters for the clock time complication.
|
||||||
|
|||||||
@@ -30,14 +30,15 @@ import com.android.systemui.dagger.qualifiers.Main
|
|||||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin
|
import com.android.systemui.plugins.BcSmartspaceDataPlugin
|
||||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
|
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
|
||||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
|
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceView
|
||||||
|
import com.android.systemui.plugins.BcSmartspaceDataPlugin.UI_SURFACE_DREAM
|
||||||
import com.android.systemui.smartspace.SmartspacePrecondition
|
import com.android.systemui.smartspace.SmartspacePrecondition
|
||||||
import com.android.systemui.smartspace.SmartspaceTargetFilter
|
import com.android.systemui.smartspace.SmartspaceTargetFilter
|
||||||
|
import com.android.systemui.smartspace.dagger.SmartspaceModule
|
||||||
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_DATA_PLUGIN
|
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_DATA_PLUGIN
|
||||||
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_PRECONDITION
|
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_PRECONDITION
|
||||||
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_TARGET_FILTER
|
import com.android.systemui.smartspace.dagger.SmartspaceModule.Companion.DREAM_SMARTSPACE_TARGET_FILTER
|
||||||
import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
|
import com.android.systemui.smartspace.dagger.SmartspaceViewComponent
|
||||||
import com.android.systemui.util.concurrency.Execution
|
import com.android.systemui.util.concurrency.Execution
|
||||||
import java.lang.RuntimeException
|
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -56,13 +57,16 @@ class DreamSmartspaceController @Inject constructor(
|
|||||||
@Named(DREAM_SMARTSPACE_PRECONDITION) private val precondition: SmartspacePrecondition,
|
@Named(DREAM_SMARTSPACE_PRECONDITION) private val precondition: SmartspacePrecondition,
|
||||||
@Named(DREAM_SMARTSPACE_TARGET_FILTER)
|
@Named(DREAM_SMARTSPACE_TARGET_FILTER)
|
||||||
private val optionalTargetFilter: Optional<SmartspaceTargetFilter>,
|
private val optionalTargetFilter: Optional<SmartspaceTargetFilter>,
|
||||||
@Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>
|
@Named(DREAM_SMARTSPACE_DATA_PLUGIN) optionalPlugin: Optional<BcSmartspaceDataPlugin>,
|
||||||
|
@Named(SmartspaceModule.WEATHER_SMARTSPACE_DATA_PLUGIN)
|
||||||
|
optionalWeatherPlugin: Optional<BcSmartspaceDataPlugin>,
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "DreamSmartspaceCtrlr"
|
private const val TAG = "DreamSmartspaceCtrlr"
|
||||||
}
|
}
|
||||||
|
|
||||||
private var session: SmartspaceSession? = null
|
private var session: SmartspaceSession? = null
|
||||||
|
private val weatherPlugin: BcSmartspaceDataPlugin? = optionalWeatherPlugin.orElse(null)
|
||||||
private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null)
|
private val plugin: BcSmartspaceDataPlugin? = optionalPlugin.orElse(null)
|
||||||
private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null)
|
private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null)
|
||||||
|
|
||||||
@@ -116,31 +120,54 @@ class DreamSmartspaceController @Inject constructor(
|
|||||||
private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
|
private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets ->
|
||||||
execution.assertIsMainThread()
|
execution.assertIsMainThread()
|
||||||
|
|
||||||
|
// The weather data plugin takes unfiltered targets and performs the filtering internally.
|
||||||
|
weatherPlugin?.onTargetsAvailable(targets)
|
||||||
|
|
||||||
onTargetsAvailableUnfiltered(targets)
|
onTargetsAvailableUnfiltered(targets)
|
||||||
val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true }
|
val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true }
|
||||||
plugin?.onTargetsAvailable(filteredTargets)
|
plugin?.onTargetsAvailable(filteredTargets)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the weather view with custom layout and connects it to the weather plugin.
|
||||||
|
*/
|
||||||
|
fun buildAndConnectWeatherView(parent: ViewGroup, customView: View?): View? {
|
||||||
|
return buildAndConnectViewWithPlugin(parent, weatherPlugin, customView)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the smartspace view and connects it to the smartspace service.
|
* Constructs the smartspace view and connects it to the smartspace service.
|
||||||
*/
|
*/
|
||||||
fun buildAndConnectView(parent: ViewGroup): View? {
|
fun buildAndConnectView(parent: ViewGroup): View? {
|
||||||
|
return buildAndConnectViewWithPlugin(parent, plugin, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildAndConnectViewWithPlugin(
|
||||||
|
parent: ViewGroup,
|
||||||
|
smartspaceDataPlugin: BcSmartspaceDataPlugin?,
|
||||||
|
customView: View?
|
||||||
|
): View? {
|
||||||
execution.assertIsMainThread()
|
execution.assertIsMainThread()
|
||||||
|
|
||||||
if (!precondition.conditionsMet()) {
|
if (!precondition.conditionsMet()) {
|
||||||
throw RuntimeException("Cannot build view when not enabled")
|
throw RuntimeException("Cannot build view when not enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
val view = buildView(parent)
|
val view = buildView(parent, smartspaceDataPlugin, customView)
|
||||||
|
|
||||||
connectSession()
|
connectSession()
|
||||||
|
|
||||||
return view
|
return view
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildView(parent: ViewGroup): View? {
|
private fun buildView(
|
||||||
return if (plugin != null) {
|
parent: ViewGroup,
|
||||||
var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener)
|
smartspaceDataPlugin: BcSmartspaceDataPlugin?,
|
||||||
|
customView: View?
|
||||||
|
): View? {
|
||||||
|
return if (smartspaceDataPlugin != null) {
|
||||||
|
val view = smartspaceViewComponentFactory.create(parent, smartspaceDataPlugin,
|
||||||
|
stateChangeListener, customView)
|
||||||
.getView()
|
.getView()
|
||||||
if (view !is View) {
|
if (view !is View) {
|
||||||
return null
|
return null
|
||||||
@@ -157,7 +184,10 @@ class DreamSmartspaceController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun connectSession() {
|
private fun connectSession() {
|
||||||
if (plugin == null || session != null || !hasActiveSessionListeners()) {
|
if (plugin == null && weatherPlugin == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (session != null || !hasActiveSessionListeners()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,13 +196,14 @@ class DreamSmartspaceController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val newSession = smartspaceManager.createSmartspaceSession(
|
val newSession = smartspaceManager.createSmartspaceSession(
|
||||||
SmartspaceConfig.Builder(context, "dream").build()
|
SmartspaceConfig.Builder(context, UI_SURFACE_DREAM).build()
|
||||||
)
|
)
|
||||||
Log.d(TAG, "Starting smartspace session for dream")
|
Log.d(TAG, "Starting smartspace session for dream")
|
||||||
newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
|
newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener)
|
||||||
this.session = newSession
|
this.session = newSession
|
||||||
|
|
||||||
plugin.registerSmartspaceEventNotifier {
|
weatherPlugin?.registerSmartspaceEventNotifier { e -> session?.notifySmartspaceEvent(e) }
|
||||||
|
plugin?.registerSmartspaceEventNotifier {
|
||||||
e ->
|
e ->
|
||||||
session?.notifySmartspaceEvent(e)
|
session?.notifySmartspaceEvent(e)
|
||||||
}
|
}
|
||||||
@@ -199,22 +230,47 @@ class DreamSmartspaceController @Inject constructor(
|
|||||||
|
|
||||||
session = null
|
session = null
|
||||||
|
|
||||||
|
weatherPlugin?.registerSmartspaceEventNotifier(null)
|
||||||
|
weatherPlugin?.onTargetsAvailable(emptyList())
|
||||||
|
|
||||||
plugin?.registerSmartspaceEventNotifier(null)
|
plugin?.registerSmartspaceEventNotifier(null)
|
||||||
plugin?.onTargetsAvailable(emptyList())
|
plugin?.onTargetsAvailable(emptyList())
|
||||||
Log.d(TAG, "Ending smartspace session for dream")
|
Log.d(TAG, "Ending smartspace session for dream")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addListener(listener: SmartspaceTargetListener) {
|
fun addListener(listener: SmartspaceTargetListener) {
|
||||||
|
addAndRegisterListener(listener, plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListener(listener: SmartspaceTargetListener) {
|
||||||
|
removeAndUnregisterListener(listener, plugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addListenerForWeatherPlugin(listener: SmartspaceTargetListener) {
|
||||||
|
addAndRegisterListener(listener, weatherPlugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeListenerForWeatherPlugin(listener: SmartspaceTargetListener) {
|
||||||
|
removeAndUnregisterListener(listener, weatherPlugin)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addAndRegisterListener(
|
||||||
|
listener: SmartspaceTargetListener,
|
||||||
|
smartspaceDataPlugin: BcSmartspaceDataPlugin?
|
||||||
|
) {
|
||||||
execution.assertIsMainThread()
|
execution.assertIsMainThread()
|
||||||
plugin?.registerListener(listener)
|
smartspaceDataPlugin?.registerListener(listener)
|
||||||
listeners.add(listener)
|
listeners.add(listener)
|
||||||
|
|
||||||
connectSession()
|
connectSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeListener(listener: SmartspaceTargetListener) {
|
private fun removeAndUnregisterListener(
|
||||||
|
listener: SmartspaceTargetListener,
|
||||||
|
smartspaceDataPlugin: BcSmartspaceDataPlugin?
|
||||||
|
) {
|
||||||
execution.assertIsMainThread()
|
execution.assertIsMainThread()
|
||||||
plugin?.unregisterListener(listener)
|
smartspaceDataPlugin?.unregisterListener(listener)
|
||||||
listeners.remove(listener)
|
listeners.remove(listener)
|
||||||
disconnect()
|
disconnect()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ interface SmartspaceViewComponent {
|
|||||||
fun create(
|
fun create(
|
||||||
@BindsInstance parent: ViewGroup,
|
@BindsInstance parent: ViewGroup,
|
||||||
@BindsInstance @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
|
@BindsInstance @Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
|
||||||
@BindsInstance onAttachListener: View.OnAttachStateChangeListener
|
@BindsInstance onAttachListener: View.OnAttachStateChangeListener,
|
||||||
|
@BindsInstance viewWithCustomLayout: View? = null
|
||||||
): SmartspaceViewComponent
|
): SmartspaceViewComponent
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,10 +54,13 @@ interface SmartspaceViewComponent {
|
|||||||
falsingManager: FalsingManager,
|
falsingManager: FalsingManager,
|
||||||
parent: ViewGroup,
|
parent: ViewGroup,
|
||||||
@Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
|
@Named(PLUGIN) plugin: BcSmartspaceDataPlugin,
|
||||||
|
viewWithCustomLayout: View?,
|
||||||
onAttachListener: View.OnAttachStateChangeListener
|
onAttachListener: View.OnAttachStateChangeListener
|
||||||
):
|
):
|
||||||
BcSmartspaceDataPlugin.SmartspaceView {
|
BcSmartspaceDataPlugin.SmartspaceView {
|
||||||
val ssView = plugin.getView(parent)
|
val ssView = viewWithCustomLayout
|
||||||
|
as? BcSmartspaceDataPlugin.SmartspaceView
|
||||||
|
?: plugin.getView(parent)
|
||||||
// Currently, this is only used to provide SmartspaceView on Dream surface.
|
// Currently, this is only used to provide SmartspaceView on Dream surface.
|
||||||
ssView.setUiSurface(UI_SURFACE_DREAM)
|
ssView.setUiSurface(UI_SURFACE_DREAM)
|
||||||
ssView.registerDataProvider(plugin)
|
ssView.registerDataProvider(plugin)
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.testing.AndroidTestingRunner
|
|||||||
import android.testing.TestableLooper
|
import android.testing.TestableLooper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.FrameLayout
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.dreams.smartspace.DreamSmartspaceController
|
import com.android.systemui.dreams.smartspace.DreamSmartspaceController
|
||||||
@@ -46,6 +47,7 @@ import org.mockito.Mock
|
|||||||
import org.mockito.Mockito
|
import org.mockito.Mockito
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.`when`
|
import org.mockito.Mockito.`when`
|
||||||
|
import org.mockito.Mockito.anyInt
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import org.mockito.Spy
|
import org.mockito.Spy
|
||||||
|
|
||||||
@@ -68,12 +70,21 @@ class DreamSmartspaceControllerTest : SysuiTestCase() {
|
|||||||
@Mock
|
@Mock
|
||||||
private lateinit var viewComponent: SmartspaceViewComponent
|
private lateinit var viewComponent: SmartspaceViewComponent
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var weatherViewComponent: SmartspaceViewComponent
|
||||||
|
|
||||||
|
@Spy
|
||||||
|
private var weatherSmartspaceView: SmartspaceView = TestView(context)
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var targetFilter: SmartspaceTargetFilter
|
private lateinit var targetFilter: SmartspaceTargetFilter
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var plugin: BcSmartspaceDataPlugin
|
private lateinit var plugin: BcSmartspaceDataPlugin
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private lateinit var weatherPlugin: BcSmartspaceDataPlugin
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var precondition: SmartspacePrecondition
|
private lateinit var precondition: SmartspacePrecondition
|
||||||
|
|
||||||
@@ -88,6 +99,9 @@ class DreamSmartspaceControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
private lateinit var controller: DreamSmartspaceController
|
private lateinit var controller: DreamSmartspaceController
|
||||||
|
|
||||||
|
// TODO(b/272811280): Remove usage of real view
|
||||||
|
private val fakeParent = FrameLayout(context)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which implements SmartspaceView and extends View. This is mocked to provide the right
|
* A class which implements SmartspaceView and extends View. This is mocked to provide the right
|
||||||
* object inheritance and interface implementation used in DreamSmartspaceController
|
* object inheritance and interface implementation used in DreamSmartspaceController
|
||||||
@@ -121,13 +135,17 @@ class DreamSmartspaceControllerTest : SysuiTestCase() {
|
|||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
`when`(viewComponentFactory.create(any(), eq(plugin), any()))
|
`when`(viewComponentFactory.create(any(), eq(plugin), any(), eq(null)))
|
||||||
.thenReturn(viewComponent)
|
.thenReturn(viewComponent)
|
||||||
`when`(viewComponent.getView()).thenReturn(smartspaceView)
|
`when`(viewComponent.getView()).thenReturn(smartspaceView)
|
||||||
|
`when`(viewComponentFactory.create(any(), eq(weatherPlugin), any(), any()))
|
||||||
|
.thenReturn(weatherViewComponent)
|
||||||
|
`when`(weatherViewComponent.getView()).thenReturn(weatherSmartspaceView)
|
||||||
`when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(session)
|
`when`(smartspaceManager.createSmartspaceSession(any())).thenReturn(session)
|
||||||
|
|
||||||
controller = DreamSmartspaceController(context, smartspaceManager, execution, uiExecutor,
|
controller = DreamSmartspaceController(context, smartspaceManager, execution, uiExecutor,
|
||||||
viewComponentFactory, precondition, Optional.of(targetFilter), Optional.of(plugin))
|
viewComponentFactory, precondition, Optional.of(targetFilter), Optional.of(plugin),
|
||||||
|
Optional.of(weatherPlugin))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -168,11 +186,11 @@ class DreamSmartspaceControllerTest : SysuiTestCase() {
|
|||||||
`when`(precondition.conditionsMet()).thenReturn(true)
|
`when`(precondition.conditionsMet()).thenReturn(true)
|
||||||
controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
|
controller.buildAndConnectView(Mockito.mock(ViewGroup::class.java))
|
||||||
|
|
||||||
var stateChangeListener = withArgCaptor<View.OnAttachStateChangeListener> {
|
val stateChangeListener = withArgCaptor<View.OnAttachStateChangeListener> {
|
||||||
verify(viewComponentFactory).create(any(), eq(plugin), capture())
|
verify(viewComponentFactory).create(any(), eq(plugin), capture(), eq(null))
|
||||||
}
|
}
|
||||||
|
|
||||||
var mockView = Mockito.mock(TestView::class.java)
|
val mockView = Mockito.mock(TestView::class.java)
|
||||||
`when`(precondition.conditionsMet()).thenReturn(true)
|
`when`(precondition.conditionsMet()).thenReturn(true)
|
||||||
stateChangeListener.onViewAttachedToWindow(mockView)
|
stateChangeListener.onViewAttachedToWindow(mockView)
|
||||||
|
|
||||||
@@ -183,4 +201,74 @@ class DreamSmartspaceControllerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
verify(session).close()
|
verify(session).close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures session is created when weather smartspace view is created and attached.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun testConnectOnWeatherViewCreate() {
|
||||||
|
`when`(precondition.conditionsMet()).thenReturn(true)
|
||||||
|
|
||||||
|
val customView = Mockito.mock(TestView::class.java)
|
||||||
|
val weatherView = controller.buildAndConnectWeatherView(fakeParent, customView)
|
||||||
|
val weatherSmartspaceView = weatherView as SmartspaceView
|
||||||
|
fakeParent.addView(weatherView)
|
||||||
|
|
||||||
|
// Then weather view is created with custom view and the default weatherPlugin.getView
|
||||||
|
// should not be called
|
||||||
|
verify(viewComponentFactory).create(eq(fakeParent), eq(weatherPlugin), any(),
|
||||||
|
eq(customView))
|
||||||
|
verify(weatherPlugin, Mockito.never()).getView(fakeParent)
|
||||||
|
|
||||||
|
// And then session is created
|
||||||
|
controller.stateChangeListener.onViewAttachedToWindow(weatherView)
|
||||||
|
verify(smartspaceManager).createSmartspaceSession(any())
|
||||||
|
verify(weatherSmartspaceView).setPrimaryTextColor(anyInt())
|
||||||
|
verify(weatherSmartspaceView).setDozeAmount(0f)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures weather plugin registers target listener when it is added from the controller.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun testAddListenerInController_registersListenerForWeatherPlugin() {
|
||||||
|
val customView = Mockito.mock(TestView::class.java)
|
||||||
|
`when`(precondition.conditionsMet()).thenReturn(true)
|
||||||
|
|
||||||
|
// Given a session is created
|
||||||
|
val weatherView = controller.buildAndConnectWeatherView(fakeParent, customView)
|
||||||
|
controller.stateChangeListener.onViewAttachedToWindow(weatherView)
|
||||||
|
verify(smartspaceManager).createSmartspaceSession(any())
|
||||||
|
|
||||||
|
// When a listener is added
|
||||||
|
controller.addListenerForWeatherPlugin(listener)
|
||||||
|
|
||||||
|
// Then the listener is registered to the weather plugin only
|
||||||
|
verify(weatherPlugin).registerListener(listener)
|
||||||
|
verify(plugin, Mockito.never()).registerListener(any())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures session is closed and weather plugin unregisters the notifier when weather smartspace
|
||||||
|
* view is detached.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
fun testDisconnect_emitsEmptyListAndRemovesNotifier() {
|
||||||
|
`when`(precondition.conditionsMet()).thenReturn(true)
|
||||||
|
|
||||||
|
// Given a session is created
|
||||||
|
val customView = Mockito.mock(TestView::class.java)
|
||||||
|
val weatherView = controller.buildAndConnectWeatherView(fakeParent, customView)
|
||||||
|
controller.stateChangeListener.onViewAttachedToWindow(weatherView)
|
||||||
|
verify(smartspaceManager).createSmartspaceSession(any())
|
||||||
|
|
||||||
|
// When view is detached
|
||||||
|
controller.stateChangeListener.onViewDetachedFromWindow(weatherView)
|
||||||
|
// Then the session is closed
|
||||||
|
verify(session).close()
|
||||||
|
|
||||||
|
// And the listener receives an empty list of targets and unregisters the notifier
|
||||||
|
verify(weatherPlugin).onTargetsAvailable(emptyList())
|
||||||
|
verify(weatherPlugin).registerSmartspaceEventNotifier(null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user