Merge changes from topic "261420432" into tm-qpr-dev

* changes:
  Introduce SelfExecutingMonitor for tests.
  Run dream logic only for current user process.
  Always have ConditionalCoreStartable subscribe to monitor.
This commit is contained in:
Bryce Lee
2023-02-14 17:01:55 +00:00
committed by Android (Google) Code Review
16 changed files with 224 additions and 38 deletions

View File

@@ -16,19 +16,23 @@
package com.android.systemui.dreams;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.util.Log;
import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.callbacks.DreamStatusBarStateCallback;
import com.android.systemui.dreams.conditions.DreamCondition;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import javax.inject.Inject;
import javax.inject.Named;
/**
* A {@link CoreStartable} to retain a monitor for tracking dreaming.
*/
public class DreamMonitor implements CoreStartable {
public class DreamMonitor extends ConditionalCoreStartable {
private static final String TAG = "DreamMonitor";
// We retain a reference to the monitor so it is not garbage-collected.
@@ -39,14 +43,17 @@ public class DreamMonitor implements CoreStartable {
@Inject
public DreamMonitor(Monitor monitor, DreamCondition dreamCondition,
@Named(DREAM_PRETEXT_MONITOR) Monitor pretextMonitor,
DreamStatusBarStateCallback callback) {
super(pretextMonitor);
mConditionMonitor = monitor;
mDreamCondition = dreamCondition;
mCallback = callback;
}
@Override
public void start() {
protected void onStart() {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "started");
}

View File

@@ -17,6 +17,7 @@
package com.android.systemui.dreams;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_OVERLAY_SERVICE_COMPONENT;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -33,8 +34,9 @@ import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.util.Log;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import javax.inject.Inject;
import javax.inject.Named;
@@ -43,7 +45,7 @@ import javax.inject.Named;
* {@link DreamOverlayRegistrant} is responsible for telling system server that SystemUI should be
* the designated dream overlay component.
*/
public class DreamOverlayRegistrant implements CoreStartable {
public class DreamOverlayRegistrant extends ConditionalCoreStartable {
private static final String TAG = "DreamOverlayRegistrant";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final IDreamManager mDreamManager;
@@ -102,7 +104,9 @@ public class DreamOverlayRegistrant implements CoreStartable {
@Inject
public DreamOverlayRegistrant(Context context, @Main Resources resources,
@Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent) {
@Named(DREAM_OVERLAY_SERVICE_COMPONENT) ComponentName dreamOverlayServiceComponent,
@Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
super(monitor);
mContext = context;
mResources = resources;
mDreamManager = IDreamManager.Stub.asInterface(
@@ -111,7 +115,7 @@ public class DreamOverlayRegistrant implements CoreStartable {
}
@Override
public void start() {
protected void onStart() {
final IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_CHANGED);
filter.addDataScheme("package");
filter.addDataSchemeSpecificPart(mOverlayServiceComponent.getPackageName(),

View File

@@ -16,27 +16,31 @@
package com.android.systemui.dreams.complication;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.database.ContentObserver;
import android.os.UserHandle;
import android.provider.Settings;
import com.android.settingslib.dream.DreamBackend;
import com.android.systemui.CoreStartable;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import com.android.systemui.util.settings.SecureSettings;
import java.util.concurrent.Executor;
import javax.inject.Inject;
import javax.inject.Named;
/**
* {@link ComplicationTypesUpdater} observes the state of available complication types set by the
* user, and pushes updates to {@link DreamOverlayStateController}.
*/
@SysUISingleton
public class ComplicationTypesUpdater implements CoreStartable {
public class ComplicationTypesUpdater extends ConditionalCoreStartable {
private final DreamBackend mDreamBackend;
private final Executor mExecutor;
private final SecureSettings mSecureSettings;
@@ -48,7 +52,9 @@ public class ComplicationTypesUpdater implements CoreStartable {
DreamBackend dreamBackend,
@Main Executor executor,
SecureSettings secureSettings,
DreamOverlayStateController dreamOverlayStateController) {
DreamOverlayStateController dreamOverlayStateController,
@Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
super(monitor);
mDreamBackend = dreamBackend;
mExecutor = executor;
mSecureSettings = secureSettings;
@@ -56,7 +62,7 @@ public class ComplicationTypesUpdater implements CoreStartable {
}
@Override
public void start() {
public void onStart() {
final ContentObserver settingsObserver = new ContentObserver(null /*handler*/) {
@Override
public void onChange(boolean selfChange) {

View File

@@ -18,11 +18,14 @@ package com.android.systemui.dreams.complication;
import static com.android.systemui.dreams.complication.dagger.DreamClockTimeComplicationModule.DREAM_CLOCK_TIME_COMPLICATION_VIEW;
import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.view.View;
import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import javax.inject.Inject;
import javax.inject.Named;
@@ -60,7 +63,7 @@ public class DreamClockTimeComplication implements Complication {
* {@link CoreStartable} responsible for registering {@link DreamClockTimeComplication} with
* SystemUI.
*/
public static class Registrant implements CoreStartable {
public static class Registrant extends ConditionalCoreStartable {
private final DreamOverlayStateController mDreamOverlayStateController;
private final DreamClockTimeComplication mComplication;
@@ -70,13 +73,15 @@ public class DreamClockTimeComplication implements Complication {
@Inject
public Registrant(
DreamOverlayStateController dreamOverlayStateController,
DreamClockTimeComplication dreamClockTimeComplication) {
DreamClockTimeComplication dreamClockTimeComplication,
@Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
super(monitor);
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = dreamClockTimeComplication;
}
@Override
public void start() {
public void onStart() {
mDreamOverlayStateController.addComplication(mComplication);
}
}

View File

@@ -21,6 +21,7 @@ import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.
import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.UNAVAILABLE;
import static com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent.DreamHomeControlsModule.DREAM_HOME_CONTROLS_CHIP_VIEW;
import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.content.Context;
import android.content.Intent;
@@ -42,7 +43,9 @@ import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import java.util.List;
@@ -75,7 +78,7 @@ public class DreamHomeControlsComplication implements Complication {
/**
* {@link CoreStartable} for registering the complication with SystemUI on startup.
*/
public static class Registrant implements CoreStartable {
public static class Registrant extends ConditionalCoreStartable {
private final DreamHomeControlsComplication mComplication;
private final DreamOverlayStateController mDreamOverlayStateController;
private final ControlsComponent mControlsComponent;
@@ -105,14 +108,16 @@ public class DreamHomeControlsComplication implements Complication {
@Inject
public Registrant(DreamHomeControlsComplication complication,
DreamOverlayStateController dreamOverlayStateController,
ControlsComponent controlsComponent) {
ControlsComponent controlsComponent,
@Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
super(monitor);
mComplication = complication;
mControlsComponent = controlsComponent;
mDreamOverlayStateController = dreamOverlayStateController;
}
@Override
public void start() {
public void onStart() {
mControlsComponent.getControlsListingController().ifPresent(
c -> c.addCallback(mControlsCallback));
mDreamOverlayStateController.addCallback(mOverlayStateCallback);

View File

@@ -17,6 +17,7 @@
package com.android.systemui.dreams.complication;
import static com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule.DREAM_SMARTSPACE_LAYOUT_PARAMS;
import static com.android.systemui.dreams.dagger.DreamModule.DREAM_PRETEXT_MONITOR;
import android.content.Context;
import android.os.Parcelable;
@@ -28,6 +29,8 @@ import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
import java.util.List;
@@ -61,7 +64,7 @@ public class SmartSpaceComplication implements Complication {
* {@link CoreStartable} responsbile for registering {@link SmartSpaceComplication} with
* SystemUI.
*/
public static class Registrant implements CoreStartable {
public static class Registrant extends ConditionalCoreStartable {
private final DreamSmartspaceController mSmartSpaceController;
private final DreamOverlayStateController mDreamOverlayStateController;
private final SmartSpaceComplication mComplication;
@@ -81,14 +84,16 @@ public class SmartSpaceComplication implements Complication {
public Registrant(
DreamOverlayStateController dreamOverlayStateController,
SmartSpaceComplication smartSpaceComplication,
DreamSmartspaceController smartSpaceController) {
DreamSmartspaceController smartSpaceController,
@Named(DREAM_PRETEXT_MONITOR) Monitor monitor) {
super(monitor);
mDreamOverlayStateController = dreamOverlayStateController;
mComplication = smartSpaceComplication;
mSmartSpaceController = smartSpaceController;
}
@Override
public void start() {
public void onStart() {
mDreamOverlayStateController.addCallback(new DreamOverlayStateController.Callback() {
@Override
public void onStateChanged() {

View File

@@ -29,13 +29,20 @@ import com.android.systemui.dreams.DreamOverlayNotificationCountProvider;
import com.android.systemui.dreams.DreamOverlayService;
import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule;
import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule;
import com.android.systemui.process.condition.UserProcessCondition;
import com.android.systemui.shared.condition.Condition;
import com.android.systemui.shared.condition.Monitor;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
import javax.inject.Named;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.IntoSet;
/**
* Dagger Module providing Dream-related functionality.
@@ -54,6 +61,8 @@ public interface DreamModule {
String DREAM_OVERLAY_ENABLED = "dream_overlay_enabled";
String DREAM_SUPPORTED = "dream_supported";
String DREAM_PRETEXT_CONDITIONS = "dream_pretext_conditions";
String DREAM_PRETEXT_MONITOR = "dream_prtext_monitor";
/**
* Provides the dream component
@@ -112,4 +121,19 @@ public interface DreamModule {
static boolean providesDreamSupported(@Main Resources resources) {
return resources.getBoolean(com.android.internal.R.bool.config_dreamsSupported);
}
/** */
@Binds
@IntoSet
@Named(DREAM_PRETEXT_CONDITIONS)
Condition bindsUserProcessCondition(UserProcessCondition condition);
/** */
@Provides
@Named(DREAM_PRETEXT_MONITOR)
static Monitor providesDockerPretextMonitor(
@Main Executor executor,
@Named(DREAM_PRETEXT_CONDITIONS) Set<Condition> pretextConditions) {
return new Monitor(executor, pretextConditions);
}
}

View File

@@ -16,11 +16,16 @@
package com.android.systemui.process;
import javax.inject.Inject;
/**
* A simple wrapper that provides access to process-related details. This facilitates testing by
* providing a mockable target around these details.
*/
public class ProcessWrapper {
@Inject
public ProcessWrapper() {}
public int getUserHandleIdentifier() {
return android.os.Process.myUserHandle().getIdentifier();
}

View File

@@ -43,11 +43,6 @@ public abstract class ConditionalCoreStartable implements CoreStartable {
@Override
public final void start() {
if (mConditionSet == null || mConditionSet.isEmpty()) {
onStart();
return;
}
mStartToken = mMonitor.addSubscription(
new Monitor.Subscription.Builder(allConditionsMet -> {
if (allConditionsMet) {
@@ -63,11 +58,6 @@ public abstract class ConditionalCoreStartable implements CoreStartable {
@Override
public final void onBootCompleted() {
if (mConditionSet == null || mConditionSet.isEmpty()) {
bootCompleted();
return;
}
mBootCompletedToken = mMonitor.addSubscription(
new Monitor.Subscription.Builder(allConditionsMet -> {
if (allConditionsMet) {

View File

@@ -32,7 +32,9 @@ import androidx.test.filters.SmallTest;
import com.android.settingslib.dream.DreamBackend;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.condition.SelfExecutingMonitor;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
import com.android.systemui.util.time.FakeSystemClock;
@@ -66,13 +68,16 @@ public class ComplicationTypesUpdaterTest extends SysuiTestCase {
private ComplicationTypesUpdater mController;
private Monitor mMonitor;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(mDreamBackend.getEnabledComplications()).thenReturn(new HashSet<>());
mMonitor = SelfExecutingMonitor.createInstance();
mController = new ComplicationTypesUpdater(mDreamBackend, mExecutor,
mSecureSettings, mDreamOverlayStateController);
mSecureSettings, mDreamOverlayStateController, mMonitor);
}
@Test

View File

@@ -29,7 +29,9 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.condition.SelfExecutingMonitor;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.shared.condition.Monitor;
import org.junit.Before;
import org.junit.Test;
@@ -69,10 +71,13 @@ public class DreamClockTimeComplicationTest extends SysuiTestCase {
@Mock
private ComplicationLayoutParams mLayoutParams;
private Monitor mMonitor;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
when(mDreamClockTimeViewHolderProvider.get()).thenReturn(mDreamClockTimeViewHolder);
mMonitor = SelfExecutingMonitor.createInstance();
}
/**
@@ -83,7 +88,8 @@ public class DreamClockTimeComplicationTest extends SysuiTestCase {
final DreamClockTimeComplication.Registrant registrant =
new DreamClockTimeComplication.Registrant(
mDreamOverlayStateController,
mComplication);
mComplication,
mMonitor);
registrant.start();
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}

View File

@@ -38,6 +38,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.view.LaunchableImageView;
import com.android.systemui.condition.SelfExecutingMonitor;
import com.android.systemui.controls.ControlsServiceInfo;
import com.android.systemui.controls.controller.ControlsController;
import com.android.systemui.controls.controller.StructureInfo;
@@ -46,6 +47,7 @@ import com.android.systemui.controls.management.ControlsListingController;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.complication.dagger.DreamHomeControlsComplicationComponent;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.shared.condition.Monitor;
import org.junit.Before;
import org.junit.Test;
@@ -101,6 +103,8 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
@Captor
private ArgumentCaptor<DreamOverlayStateController.Callback> mStateCallbackCaptor;
private Monitor mMonitor;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -112,6 +116,8 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
Optional.of(mControlsListingController));
when(mControlsComponent.getVisibility()).thenReturn(AVAILABLE);
when(mView.findViewById(R.id.home_controls_chip)).thenReturn(mHomeControlsView);
mMonitor = SelfExecutingMonitor.createInstance();
}
@Test
@@ -126,7 +132,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_serviceNotAvailable_noFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -139,7 +145,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_serviceAvailable_noFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -152,7 +158,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_serviceAvailable_noFavorites_panel_addComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(false);
@@ -165,7 +171,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_serviceNotAvailable_haveFavorites_doNotAddComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(true);
@@ -178,7 +184,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_serviceAvailable_haveFavorites_addComplication() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setHaveFavorites(true);
@@ -191,7 +197,7 @@ public class DreamHomeControlsComplicationTest extends SysuiTestCase {
public void complicationAvailability_checkAvailabilityWhenDreamOverlayBecomesActive() {
final DreamHomeControlsComplication.Registrant registrant =
new DreamHomeControlsComplication.Registrant(mComplication,
mDreamOverlayStateController, mControlsComponent);
mDreamOverlayStateController, mControlsComponent, mMonitor);
registrant.start();
setServiceAvailable(true);

View File

@@ -30,9 +30,12 @@ import android.view.View;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.condition.SelfExecutingMonitor;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.dreams.smartspace.DreamSmartspaceController;
import com.android.systemui.plugins.BcSmartspaceDataPlugin;
import com.android.systemui.shared.condition.Condition;
import com.android.systemui.shared.condition.Monitor;
import org.junit.Before;
import org.junit.Test;
@@ -43,6 +46,8 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -60,9 +65,14 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
@Mock
private View mBcSmartspaceView;
private Monitor mMonitor;
private final Set<Condition> mPreconditions = new HashSet<>();
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mMonitor = SelfExecutingMonitor.createInstance();
}
/**
@@ -79,7 +89,8 @@ public class SmartSpaceComplicationTest extends SysuiTestCase {
return new SmartSpaceComplication.Registrant(
mDreamOverlayStateController,
mComplication,
mSmartspaceController);
mSmartspaceController,
mMonitor);
}
@Test

View File

@@ -248,6 +248,21 @@ public class ConditionMonitorTest extends SysuiTestCase {
verify(callback).onConditionsChanged(true);
}
@Test
public void addCallback_preCondition_noConditions_reportAllConditionsMet() {
final Monitor
monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1)));
final Monitor.Callback callback = mock(
Monitor.Callback.class);
monitor.addSubscription(new Monitor.Subscription.Builder(callback).build());
mExecutor.runAllReady();
verify(callback, never()).onConditionsChanged(true);
mCondition1.fakeUpdateCondition(true);
mExecutor.runAllReady();
verify(callback).onConditionsChanged(true);
}
@Test
public void removeCallback_noFailureOnDoubleRemove() {
final Condition condition = mock(

View File

@@ -60,6 +60,11 @@ public class ConditionalCoreStartableTest extends SysuiTestCase {
mCallback = callback;
}
public FakeConditionalCoreStartable(Monitor monitor, Callback callback) {
super(monitor);
mCallback = callback;
}
@Override
protected void onStart() {
mCallback.onStart();
@@ -122,6 +127,31 @@ public class ConditionalCoreStartableTest extends SysuiTestCase {
verify(mMonitor).removeSubscription(mSubscriptionToken);
}
@Test
public void testOnStartCallbackWithNoConditions() {
final CoreStartable coreStartable =
new FakeConditionalCoreStartable(mMonitor,
mCallback);
when(mMonitor.addSubscription(any())).thenReturn(mSubscriptionToken);
coreStartable.start();
final ArgumentCaptor<Monitor.Subscription> subscriptionCaptor = ArgumentCaptor.forClass(
Monitor.Subscription.class);
verify(mMonitor).addSubscription(subscriptionCaptor.capture());
final Monitor.Subscription subscription = subscriptionCaptor.getValue();
assertThat(subscription.getConditions()).isEmpty();
verify(mCallback, never()).onStart();
subscription.getCallback().onConditionsChanged(true);
verify(mCallback).onStart();
verify(mMonitor).removeSubscription(mSubscriptionToken);
}
/**
* Verifies that {@link ConditionalCoreStartable#bootCompleted()} ()} is predicated on

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.condition;
import androidx.annotation.NonNull;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
/**
* {@link SelfExecutingMonitor} creates a monitor that independently executes its logic through
* a {@link FakeExecutor}, which is ran at when a subscription is added and removed.
*/
public class SelfExecutingMonitor extends Monitor {
private final FakeExecutor mExecutor;
/**
* Default constructor that allows specifying the FakeExecutor to use.
*/
public SelfExecutingMonitor(FakeExecutor executor) {
super(executor);
mExecutor = executor;
}
@Override
public Subscription.Token addSubscription(@NonNull Subscription subscription) {
final Subscription.Token result = super.addSubscription(subscription);
mExecutor.runAllReady();
return result;
}
@Override
public void removeSubscription(@NonNull Subscription.Token token) {
super.removeSubscription(token);
mExecutor.runNextReady();
}
/**
* Creates a {@link SelfExecutingMonitor} with a self-managed {@link FakeExecutor}. Use only
* for cases where condition state only will be set at when a subscription is added.
*/
public static SelfExecutingMonitor createInstance() {
final FakeSystemClock mFakeSystemClock = new FakeSystemClock();
final FakeExecutor mExecutor = new FakeExecutor(mFakeSystemClock);
return new SelfExecutingMonitor(mExecutor);
}
}