Merge "Add unfiltered access to the dream smartspace targets, in order to extract weather data." into tm-qpr-dev am: 2d08c91009 am: 219633931d
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18759911 Change-Id: I739ccb2ae0c4f4cdf74962d67e425e42c594e420 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -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<TextView> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<BcSmartspaceDataPlugin.SmartspaceTargetListener>()
|
||||
private var listeners = mutableSetOf<SmartspaceTargetListener>()
|
||||
|
||||
private var unfilteredListeners = mutableSetOf<SmartspaceTargetListener>()
|
||||
|
||||
// Smartspace can be used on multiple displays, such as when the user casts their screen
|
||||
private var smartspaceViews = mutableSetOf<SmartspaceView>()
|
||||
@@ -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<SmartspaceTarget>) {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user