Skip to content

Commit

Permalink
Allowing ShadowSensorManager to have multiple Sensors of the same typ…
Browse files Browse the repository at this point in the history
…e added

This is possible in Android, as true uniqueness between sensors comes from the pairing of a Sensor's name and type together. Changing how ShadowSensorManager stores the added Sensor instances will allow for multiple of the same time type to exist at once, more closely acting like the real thing.

Also adding an overload to sendSensorEventToListeners() method to specify which listeners to push a given SensorEvent to. If you create and register multiple Sensors with ShadowSensorManager then want to push SensorEvents to them, it makes sense to only push it to the listeners that are relevant to the given Sensor

PiperOrigin-RevId: 580322304
  • Loading branch information
Googler authored and Copybara-Service committed Nov 7, 2023
1 parent 4b4b7be commit 98361f7
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,23 @@ public void removeSensor_shouldRemoveAddedSensor() {
}

@Test
public void shouldReturnASensorList() {
assertThat(sensorManager.getSensorList(0)).isNotNull();
public void shouldReturnEmptySensorListIfNoneCreated() {
assertThat(sensorManager.getSensorList(0)).isEmpty();
}

@Test
public void shouldReturnAllRelevantSensorsForGivenType() {
ShadowSensorManager shadowSensorManager = shadowOf(sensorManager);
Sensor gyroscopeSensor1 = ShadowSensor.newInstance(TYPE_GYROSCOPE);
Sensor gyroscopeSensor2 = ShadowSensor.newInstance(TYPE_GYROSCOPE);
Sensor irrelevantAccelSensor1 = ShadowSensor.newInstance(TYPE_ACCELEROMETER);

shadowSensorManager.addSensor(gyroscopeSensor1);
shadowSensorManager.addSensor(gyroscopeSensor2);
shadowSensorManager.addSensor(irrelevantAccelSensor1);
List<Sensor> allGyroSensors = sensorManager.getSensorList(TYPE_GYROSCOPE);

assertThat(allGyroSensors).containsExactly(gyroscopeSensor1, gyroscopeSensor2);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
Expand All @@ -31,9 +31,10 @@
@Implements(value = SensorManager.class, looseSignatures = true)
public class ShadowSensorManager {
public boolean forceListenersToFail = false;
private final Map<Integer, Sensor> sensorMap = new HashMap<>();
private final Multimap<Integer, Sensor> sensorMap =
Multimaps.synchronizedMultimap(HashMultimap.create());
private final Multimap<SensorEventListener, Sensor> listeners =
Multimaps.synchronizedMultimap(HashMultimap.<SensorEventListener, Sensor>create());
Multimaps.synchronizedMultimap(HashMultimap.create());

@RealObject private SensorManager realObject;

Expand All @@ -60,12 +61,17 @@ public void addSensor(Sensor sensor) {

public void removeSensor(Sensor sensor) {
checkNotNull(sensor);
sensorMap.remove(sensor.getType());
sensorMap.get(sensor.getType()).remove(sensor);
}

@Implementation
protected Sensor getDefaultSensor(int type) {
return sensorMap.get(type);
Collection<Sensor> sensorsForType = sensorMap.get(type);
if (sensorsForType.isEmpty()) {
return null;
}

return ((Sensor) sensorsForType.toArray()[0]);
}

@Implementation
Expand All @@ -74,12 +80,7 @@ public List<Sensor> getSensorList(int type) {
return ImmutableList.copyOf(sensorMap.values());
}

List<Sensor> sensorList = new ArrayList<>();
Sensor sensor = sensorMap.get(type);
if (sensor != null) {
sensorList.add(sensor);
}
return sensorList;
return ImmutableList.copyOf(sensorMap.get(type));
}

/** @param handler is ignored. */
Expand Down Expand Up @@ -152,6 +153,20 @@ public void sendSensorEventToListeners(SensorEvent event) {
}
}

/** Propagates the {@code event} to only registered listeners of the given sensor. */
@SuppressWarnings("JdkCollectors") // toImmutableList is only supported in Java 8+.
public void sendSensorEventToListeners(SensorEvent event, Sensor sensor) {
List<SensorEventListener> listenersRegisteredToSensor =
listeners.entries().stream()
.filter(entry -> entry.getValue() == sensor)
.map(Entry::getKey)
.collect(Collectors.toList());

for (SensorEventListener listener : listenersRegisteredToSensor) {
listener.onSensorChanged(event);
}
}

@Implementation(minSdk = KITKAT)
protected boolean flush(SensorEventListener listener) {
// ShadowSensorManager doesn't queue up any sensor events, so nothing actually needs to be
Expand Down

0 comments on commit 98361f7

Please sign in to comment.