Merge "Remove SmartSpaceComplication when the SmartspaceTargetListener is removed." into tm-qpr-dev

This commit is contained in:
Xiaowen Lei
2022-06-23 16:23:06 +00:00
committed by Android (Google) Code Review
6 changed files with 107 additions and 9 deletions

View File

@@ -101,6 +101,9 @@ public class DreamOverlayStateController implements
public void addComplication(Complication complication) { public void addComplication(Complication complication) {
mExecutor.execute(() -> { mExecutor.execute(() -> {
if (mComplications.add(complication)) { if (mComplications.add(complication)) {
if (DEBUG) {
Log.d(TAG, "addComplication: added " + complication);
}
mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged()); mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
} }
}); });
@@ -112,6 +115,9 @@ public class DreamOverlayStateController implements
public void removeComplication(Complication complication) { public void removeComplication(Complication complication) {
mExecutor.execute(() -> { mExecutor.execute(() -> {
if (mComplications.remove(complication)) { if (mComplications.remove(complication)) {
if (DEBUG) {
Log.d(TAG, "removeComplication: removed " + complication);
}
mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged()); mCallbacks.stream().forEach(callback -> callback.onComplicationsChanged());
} }
}); });

View File

@@ -82,6 +82,7 @@ public class SmartSpaceComplication implements Complication {
mSmartSpaceController.addListener(mSmartspaceListener); mSmartSpaceController.addListener(mSmartspaceListener);
} else { } else {
mSmartSpaceController.removeListener(mSmartspaceListener); mSmartSpaceController.removeListener(mSmartspaceListener);
mDreamOverlayStateController.removeComplication(mComplication);
} }
} }
}); });

View File

@@ -21,6 +21,7 @@ import static com.android.systemui.dreams.complication.dagger.ComplicationModule
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.Region; import android.graphics.Region;
import android.os.Debug;
import android.util.Log; import android.util.Log;
import android.view.View; import android.view.View;
@@ -44,7 +45,8 @@ import javax.inject.Named;
* a {@link ComplicationLayoutEngine}. * a {@link ComplicationLayoutEngine}.
*/ */
public class ComplicationHostViewController extends ViewController<ConstraintLayout> { public class ComplicationHostViewController extends ViewController<ConstraintLayout> {
public static final String TAG = "ComplicationHostVwCtrl"; private static final String TAG = "ComplicationHostVwCtrl";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final ComplicationLayoutEngine mLayoutEngine; private final ComplicationLayoutEngine mLayoutEngine;
private final LifecycleOwner mLifecycleOwner; private final LifecycleOwner mLifecycleOwner;
@@ -90,6 +92,11 @@ public class ComplicationHostViewController extends ViewController<ConstraintLay
} }
private void updateComplications(Collection<ComplicationViewModel> complications) { private void updateComplications(Collection<ComplicationViewModel> complications) {
if (DEBUG) {
Log.d(TAG, "updateComplications called. Callers = " + Debug.getCallers(25));
Log.d(TAG, " mComplications = " + mComplications.toString());
Log.d(TAG, " complications = " + complications.toString());
}
final Collection<ComplicationId> ids = complications.stream() final Collection<ComplicationId> ids = complications.stream()
.map(complicationViewModel -> complicationViewModel.getId()) .map(complicationViewModel -> complicationViewModel.getId())
.collect(Collectors.toSet()); .collect(Collectors.toSet());

View File

@@ -54,7 +54,7 @@ import javax.inject.Named;
*/ */
@DreamOverlayComponent.DreamOverlayScope @DreamOverlayComponent.DreamOverlayScope
public class ComplicationLayoutEngine implements Complication.VisibilityController { public class ComplicationLayoutEngine implements Complication.VisibilityController {
public static final String TAG = "ComplicationLayoutEngine"; public static final String TAG = "ComplicationLayoutEng";
/** /**
* {@link ViewEntry} is an internal container, capturing information necessary for working with * {@link ViewEntry} is an internal container, capturing information necessary for working with
@@ -529,7 +529,7 @@ public class ComplicationLayoutEngine implements Complication.VisibilityControll
*/ */
public void addComplication(ComplicationId id, View view, public void addComplication(ComplicationId id, View view,
ComplicationLayoutParams lp, @Complication.Category int category) { ComplicationLayoutParams lp, @Complication.Category int category) {
Log.d(TAG, "engine: " + this + " addComplication"); Log.d(TAG, "@" + Integer.toHexString(this.hashCode()) + " addComplication: " + id);
// If the complication is present, remove. // If the complication is present, remove.
if (mEntries.containsKey(id)) { if (mEntries.containsKey(id)) {

View File

@@ -64,4 +64,9 @@ public class ComplicationViewModel extends ViewModel {
public void exitDream() { public void exitDream() {
mHost.requestExitDream(); mHost.requestExitDream();
} }
@Override
public String toString() {
return mId + "=" + mComplication.toString();
}
} }

View File

@@ -72,19 +72,67 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
} }
/** /**
* Ensures {@link SmartSpaceComplication} is only registered when it is available. * Ensures {@link SmartSpaceComplication} isn't registered right away on start.
*/ */
@Test @Test
public void testAvailability() { public void testRegistrantStart_doesNotAddComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
}
final SmartSpaceComplication.Registrant registrant = new SmartSpaceComplication.Registrant( private SmartSpaceComplication.Registrant getRegistrant() {
return new SmartSpaceComplication.Registrant(
mContext, mContext,
mDreamOverlayStateController, mDreamOverlayStateController,
mComplication, mComplication,
mSmartspaceController); mSmartspaceController);
registrant.start(); }
verify(mDreamOverlayStateController, never()).addComplication(eq(mComplication));
@Test
public void testOverlayActive_addsTargetListener() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
dreamCallbackCaptor.getValue().onStateChanged();
// Test
final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
}
@Test
public void testOverlayActive_targetsNonEmpty_addsComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
dreamCallbackCaptor.getValue().onStateChanged();
final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
// Test
final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
@Test
public void testOverlayActive_targetsEmpty_removesComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor = final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class); ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
@@ -100,10 +148,41 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class); final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target)); listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication)); verify(mDreamOverlayStateController).addComplication(eq(mComplication));
// Test
listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList());
verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
} }
@Test @Test
public void testGetViewReusesSameView() { public void testOverlayInActive_removesTargetListener_removesComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
final ArgumentCaptor<DreamOverlayStateController.Callback> dreamCallbackCaptor =
ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
verify(mDreamOverlayStateController).addCallback(dreamCallbackCaptor.capture());
when(mDreamOverlayStateController.isOverlayActive()).thenReturn(true);
dreamCallbackCaptor.getValue().onStateChanged();
final ArgumentCaptor<BcSmartspaceDataPlugin.SmartspaceTargetListener> listenerCaptor =
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
// Test
when(mDreamOverlayStateController.isOverlayActive()).thenReturn(false);
dreamCallbackCaptor.getValue().onStateChanged();
verify(mSmartspaceController).removeListener(listenerCaptor.getValue());
verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
}
@Test
public void testGetView_reusesSameView() {
final SmartSpaceComplication complication = new SmartSpaceComplication(getContext(), final SmartSpaceComplication complication = new SmartSpaceComplication(getContext(),
mSmartspaceController); mSmartspaceController);
final Complication.ViewHolder viewHolder = complication.createView(mComplicationViewModel); final Complication.ViewHolder viewHolder = complication.createView(mComplicationViewModel);