diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java index 3d1bc59b433a7..aceafb54914a8 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java @@ -33,9 +33,9 @@ import com.android.systemui.CoreStartable; import com.android.systemui.R; import com.android.systemui.dreams.DreamOverlayStateController; import com.android.systemui.dreams.complication.dagger.DreamWeatherComplicationComponent; +import com.android.systemui.dreams.smartspace.DreamSmartspaceController; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener; -import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController; import com.android.systemui.util.ViewController; import javax.inject.Inject; @@ -73,7 +73,6 @@ public class DreamWeatherComplication implements Complication { * {@link CoreStartable} for registering {@link DreamWeatherComplication} with SystemUI. */ public static class Registrant extends CoreStartable { - private final LockscreenSmartspaceController mSmartSpaceController; private final DreamOverlayStateController mDreamOverlayStateController; private final DreamWeatherComplication mComplication; @@ -82,20 +81,16 @@ public class DreamWeatherComplication implements Complication { */ @Inject public Registrant(Context context, - LockscreenSmartspaceController smartspaceController, DreamOverlayStateController dreamOverlayStateController, DreamWeatherComplication dreamWeatherComplication) { super(context); - mSmartSpaceController = smartspaceController; mDreamOverlayStateController = dreamOverlayStateController; mComplication = dreamWeatherComplication; } @Override public void start() { - if (mSmartSpaceController.isEnabled()) { - mDreamOverlayStateController.addComplication(mComplication); - } + mDreamOverlayStateController.addComplication(mComplication); } } @@ -134,7 +129,7 @@ public class DreamWeatherComplication implements Complication { * ViewController to contain value/logic associated with a Weather Complication View. */ static class DreamWeatherViewController extends ViewController { - private final LockscreenSmartspaceController mSmartSpaceController; + private final DreamSmartspaceController mSmartSpaceController; private final ActivityStarter mActivityStarter; private final String mSmartspaceTrampolineActivityComponent; private SmartspaceTargetListener mSmartspaceTargetListener; @@ -144,7 +139,7 @@ public class DreamWeatherComplication implements Complication { @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view, @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline, ActivityStarter activityStarter, - LockscreenSmartspaceController smartspaceController + DreamSmartspaceController smartspaceController ) { super(view); mActivityStarter = activityStarter; @@ -192,12 +187,14 @@ public class DreamWeatherComplication implements Complication { }); } }); - mSmartSpaceController.addListener(mSmartspaceTargetListener); + // We need to use an unfiltered listener here since weather is filtered from showing + // in the dream smartspace. + mSmartSpaceController.addUnfilteredListener(mSmartspaceTargetListener); } @Override protected void onViewDetached() { - mSmartSpaceController.removeListener(mSmartspaceTargetListener); + mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener); } } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt index da2cf84318dec..9789cef949d33 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt +++ b/packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt @@ -19,6 +19,7 @@ package com.android.systemui.dreams.smartspace import android.app.smartspace.SmartspaceConfig import android.app.smartspace.SmartspaceManager import android.app.smartspace.SmartspaceSession +import android.app.smartspace.SmartspaceTarget import android.content.Context import android.graphics.Color import android.util.Log @@ -66,7 +67,9 @@ class DreamSmartspaceController @Inject constructor( private var targetFilter: SmartspaceTargetFilter? = optionalTargetFilter.orElse(null) // A shadow copy of listeners is maintained to track whether the session should remain open. - private var listeners = mutableSetOf() + private var listeners = mutableSetOf() + + private var unfilteredListeners = mutableSetOf() // Smartspace can be used on multiple displays, such as when the user casts their screen private var smartspaceViews = mutableSetOf() @@ -113,6 +116,7 @@ class DreamSmartspaceController @Inject constructor( private val sessionListener = SmartspaceSession.OnTargetsAvailableListener { targets -> execution.assertIsMainThread() + onTargetsAvailableUnfiltered(targets) val filteredTargets = targets.filter { targetFilter?.filterSmartspaceTarget(it) ?: true } plugin?.onTargetsAvailable(filteredTargets) } @@ -137,7 +141,7 @@ class DreamSmartspaceController @Inject constructor( private fun buildView(parent: ViewGroup): View? { return if (plugin != null) { var view = smartspaceViewComponentFactory.create(parent, plugin, stateChangeListener) - .getView() + .getView() if (view !is View) { return null } @@ -151,7 +155,8 @@ class DreamSmartspaceController @Inject constructor( } private fun hasActiveSessionListeners(): Boolean { - return smartspaceViews.isNotEmpty() || listeners.isNotEmpty() + return smartspaceViews.isNotEmpty() || listeners.isNotEmpty() || + unfilteredListeners.isNotEmpty() } private fun connectSession() { @@ -164,13 +169,15 @@ class DreamSmartspaceController @Inject constructor( } val newSession = smartspaceManager.createSmartspaceSession( - SmartspaceConfig.Builder(context, "dream").build()) + SmartspaceConfig.Builder(context, "dream").build() + ) Log.d(TAG, "Starting smartspace session for dream") newSession.addOnTargetsAvailableListener(uiExecutor, sessionListener) this.session = newSession plugin.registerSmartspaceEventNotifier { - e -> session?.notifySmartspaceEvent(e) + e -> + session?.notifySmartspaceEvent(e) } reloadSmartspace() @@ -218,4 +225,22 @@ class DreamSmartspaceController @Inject constructor( private fun reloadSmartspace() { session?.requestSmartspaceUpdate() } + + private fun onTargetsAvailableUnfiltered(targets: List) { + unfilteredListeners.forEach { it.onSmartspaceTargetsUpdated(targets) } + } + + /** + * Adds a listener for the raw, unfiltered list of smartspace targets. This should be used + * carefully, as it doesn't filter out targets which the user may not want shown. + */ + fun addUnfilteredListener(listener: SmartspaceTargetListener) { + unfilteredListeners.add(listener) + connectSession() + } + + fun removeUnfilteredListener(listener: SmartspaceTargetListener) { + unfilteredListeners.remove(listener) + disconnect() + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java index 151742af7e1a8..883bec4658159 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java @@ -17,18 +17,19 @@ package com.android.systemui.dreams.complication; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.never; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import android.content.Context; import android.testing.AndroidTestingRunner; +import android.widget.TextView; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; import com.android.systemui.dreams.DreamOverlayStateController; -import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController; +import com.android.systemui.dreams.smartspace.DreamSmartspaceController; +import com.android.systemui.plugins.ActivityStarter; import org.junit.Before; import org.junit.Test; @@ -39,12 +40,14 @@ import org.mockito.MockitoAnnotations; @SmallTest @RunWith(AndroidTestingRunner.class) public class DreamWeatherComplicationTest extends SysuiTestCase { + private static final String TRAMPOLINE_COMPONENT = "TestComponent"; + @SuppressWarnings("HidingField") @Mock private Context mContext; @Mock - private LockscreenSmartspaceController mSmartspaceController; + private DreamSmartspaceController mDreamSmartspaceController; @Mock private DreamOverlayStateController mDreamOverlayStateController; @@ -58,22 +61,28 @@ public class DreamWeatherComplicationTest extends SysuiTestCase { } /** - * Ensures {@link DreamWeatherComplication} is only registered when it is available. + * Ensures {@link DreamWeatherComplication} is registered. */ @Test - public void testComplicationAvailability() { - when(mSmartspaceController.isEnabled()).thenReturn(false); + public void testComplicationRegistered() { final DreamWeatherComplication.Registrant registrant = new DreamWeatherComplication.Registrant( mContext, - mSmartspaceController, mDreamOverlayStateController, mComplication); registrant.start(); - verify(mDreamOverlayStateController, never()).addComplication(any()); - - when(mSmartspaceController.isEnabled()).thenReturn(true); - registrant.start(); verify(mDreamOverlayStateController).addComplication(eq(mComplication)); } + + @Test + public void testGetUnfilteredTargets() { + final DreamWeatherComplication.DreamWeatherViewController controller = + new DreamWeatherComplication.DreamWeatherViewController(mock( + TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class), + mDreamSmartspaceController); + controller.onViewAttached(); + verify(mDreamSmartspaceController).addUnfilteredListener(any()); + controller.onViewDetached(); + verify(mDreamSmartspaceController).removeUnfilteredListener(any()); + } }