package org.robolectric.shadows.support.v4;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.content.LocalBroadcastManager;
import org.robolectric.Robolectric;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.Provider;
import org.robolectric.shadows.ShadowApplication;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@Implements(LocalBroadcastManager.class)
public class ShadowLocalBroadcastManager {
private final List<Intent> sentBroadcastIntents = new ArrayList<>();
private final List<Wrapper> registeredReceivers = new ArrayList<>();
@Implementation
public static LocalBroadcastManager getInstance(final Context context) {
return ShadowApplication.getInstance().getSingleton(LocalBroadcastManager.class, new Provider<LocalBroadcastManager>() {
@Override
public LocalBroadcastManager get() {
return ReflectionHelpers.callConstructor(LocalBroadcastManager.class, ClassParameter.from(Context.class, context));
}
});
}
@Implementation
public void registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
registeredReceivers.add(new Wrapper(receiver, filter));
}
@Implementation
public void unregisterReceiver(BroadcastReceiver receiver) {
Iterator<Wrapper> iterator = registeredReceivers.iterator();
while (iterator.hasNext()) {
Wrapper wrapper = iterator.next();
if (wrapper.broadcastReceiver == receiver) {
iterator.remove();
}
}
}
@Implementation
public boolean sendBroadcast(Intent intent) {
boolean sent = false;
sentBroadcastIntents.add(intent);
List<Wrapper> copy = new ArrayList<>();
copy.addAll(registeredReceivers);
for (Wrapper wrapper : copy) {
if (wrapper.intentFilter.matchAction(intent.getAction())) {
final int match = wrapper.intentFilter.matchData(intent.getType(), intent.getScheme(), intent.getData());
if (match != IntentFilter.NO_MATCH_DATA && match != IntentFilter.NO_MATCH_TYPE) {
sent = true;
final BroadcastReceiver receiver = wrapper.broadcastReceiver;
final Intent broadcastIntent = intent;
Robolectric.getForegroundThreadScheduler().post(new Runnable() {
@Override
public void run() {
receiver.onReceive(RuntimeEnvironment.application, broadcastIntent);
}
});
}
}
}
return sent;
}
public List<Intent> getSentBroadcastIntents() {
return sentBroadcastIntents;
}
public List<Wrapper> getRegisteredBroadcastReceivers() {
return registeredReceivers;
}
public static class Wrapper {
public final BroadcastReceiver broadcastReceiver;
public final IntentFilter intentFilter;
public Wrapper(BroadcastReceiver broadcastReceiver, IntentFilter intentFilter) {
this.broadcastReceiver = broadcastReceiver;
this.intentFilter = intentFilter;
}
}
}