org.ioc.commons.impl.android.flowcontrol.operationmanager.AndroidOperationManagerImpl Maven / Gradle / Ivy
package org.ioc.commons.impl.android.flowcontrol.operationmanager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ioc.commons.flowcontrol.common.BindRegistration;
import org.ioc.commons.flowcontrol.operationmanager.IsOperation;
import org.ioc.commons.flowcontrol.operationmanager.OperationHandler;
import org.ioc.commons.flowcontrol.operationmanager.OperationManager;
import org.ioc.commons.utils.Format;
import org.ioc.commons.utils.FormatterLogger;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
public class AndroidOperationManagerImpl> implements OperationManager {
private static final FormatterLogger logger = FormatterLogger.getLogger(AndroidOperationManagerImpl.class);
private static final String OPERATION_BEGINNING_INTENT_ACTION = "org.ioc.commons.impl.android.flowcontrol.operationmanager.OPERATION.BEGINNING";
private static final String OPERATION_FINISHING_INTENT_ACTION = "org.ioc.commons.impl.android.flowcontrol.operationmanager.OPERATION.FINISHING";
private static final String OPERATION_KEY = "OPERATION";
private final static String SUCCESS_KEY = "SUCCESS";
private class AndroidOperationManagerBindRegistration implements BindRegistration {
private final Context context;
private final AndroidOperationManagerImpl.OperationStore beginningOs;
private final AndroidOperationManagerImpl.OperationStore finishingOs;
public AndroidOperationManagerBindRegistration(Context context,
AndroidOperationManagerImpl.OperationStore beginningOs,
AndroidOperationManagerImpl.OperationStore finishingOs) {
this.context = context;
this.beginningOs = beginningOs;
this.finishingOs = finishingOs;
}
@Override
public void unbind() {
stored.remove(this.beginningOs);
stored.remove(this.finishingOs);
this.context.unregisterReceiver(this.beginningOs.receiver);
this.context.unregisterReceiver(this.finishingOs.receiver);
}
}
private static class OperationReceiver> extends BroadcastReceiver {
private final OperationHandler handler;
private final Map, BindRegistration> onceHandlers;
private final List onGoingOps;
private final boolean finishing;
public OperationReceiver(boolean finishing, OperationHandler handler,
Map, BindRegistration> onceHandlers) {
this(finishing, handler, onceHandlers, null);
}
public OperationReceiver(boolean finishing, OperationHandler handler,
Map, BindRegistration> onceHandlers, List onGoingOps) {
this.onGoingOps = onGoingOps;
this.finishing = finishing;
this.handler = handler;
this.onceHandlers = onceHandlers;
}
@Override
public void onReceive(Context context, Intent intent) {
if (!onceHandlers.isEmpty()) {
BindRegistration registration = onceHandlers.remove(handler);
if (registration != null) {
registration.unbind();
}
}
@SuppressWarnings("unchecked")
O operation = (O) intent.getSerializableExtra(OPERATION_KEY);
if (!finishing) {
if (onGoingOps == null || onGoingOps.size() == 1) {
handler.onOperationBeginning(context, operation);
}
} else {
if (onGoingOps == null || onGoingOps.isEmpty()) {
handler.onOperationFinished(context, operation, intent.getBooleanExtra(SUCCESS_KEY, false));
}
}
}
}
private class OperationStore {
IntentFilter filter;
OperationReceiver receiver;
O operation;
@Override
public String toString() {
return "OperationStore [filter=" + filter + ", receiver=" + receiver + ", operation=" + operation + "]";
}
}
private final Set stored = new HashSet<>();
private final Context context;
private final Map, BindRegistration> onceHandlers = new HashMap, BindRegistration>();
private final List onGoingOps = new ArrayList();
private boolean active;
public AndroidOperationManagerImpl(Context context, boolean initiallyActive) {
this.context = context;
this.active = initiallyActive;
}
@Override
public BindRegistration bindOperation(O operation, OperationHandler handler) {
IntentFilter beginningFilter = new IntentFilter(OPERATION_BEGINNING_INTENT_ACTION);
IntentFilter finishingFilter = new IntentFilter(OPERATION_FINISHING_INTENT_ACTION);
OperationReceiver beginningReceiver = new OperationReceiver(false, handler, onceHandlers);
OperationReceiver finishingReceiver = new OperationReceiver(true, handler, onceHandlers);
AndroidOperationManagerImpl.OperationStore beginningOs = addOperationReceiver(beginningFilter,
beginningReceiver, operation);
AndroidOperationManagerImpl.OperationStore finishingOs = addOperationReceiver(finishingFilter,
finishingReceiver, operation);
return new AndroidOperationManagerBindRegistration(context, beginningOs, finishingOs);
}
private OperationStore addOperationReceiver(IntentFilter filter, OperationReceiver receiver, O operation) {
OperationStore os = new OperationStore();
os.filter = filter;
os.receiver = receiver;
os.operation = operation;
stored.add(os);
if (active) {
context.registerReceiver(receiver, filter);
}
return os;
}
@Override
public BindRegistration bindOperationOnce(O operation, OperationHandler handler) {
BindRegistration registration = bindOperation(operation, handler);
this.onceHandlers.put(handler, registration);
return registration;
}
@Override
public BindRegistration bindOperationsRunning(OperationHandler handler) {
IntentFilter beginningFilter = new IntentFilter(OPERATION_BEGINNING_INTENT_ACTION);
IntentFilter finishingFilter = new IntentFilter(OPERATION_FINISHING_INTENT_ACTION);
OperationReceiver beginningReceiver = new OperationReceiver(false, handler, onceHandlers, onGoingOps);
OperationReceiver finishingReceiver = new OperationReceiver(true, handler, onceHandlers, onGoingOps);
AndroidOperationManagerImpl.OperationStore beginningOs = addOperationReceiver(beginningFilter,
beginningReceiver, null);
AndroidOperationManagerImpl.OperationStore finishingOs = addOperationReceiver(finishingFilter,
finishingReceiver, null);
return new AndroidOperationManagerBindRegistration(context, beginningOs, finishingOs);
}
@Override
public void operationBeginning(O operation) {
Log.v(this.getClass().getSimpleName(), "Beginning " + operation);
this.onGoingOps.add(operation);
Intent intent = new Intent(OPERATION_BEGINNING_INTENT_ACTION);
intent.putExtra(OPERATION_KEY, operation);
context.sendBroadcast(intent);
}
@Override
public boolean operationFinished(O operation, boolean success) {
Log.v(this.getClass().getSimpleName(),
Format.substitute("Finishing {0}. Success? {1}. Pending ops? {2}", operation, success,
this.getPendingOpCount()));
boolean removed = this.onGoingOps.remove(operation);
Intent intent = new Intent(OPERATION_FINISHING_INTENT_ACTION);
intent.putExtra(OPERATION_KEY, operation);
intent.putExtra(SUCCESS_KEY, success);
context.sendBroadcast(intent);
Log.v(this.getClass().getSimpleName(),
Format.substitute("Finished {0}. Removed? {1}. Pending ops? {2}", operation, removed,
this.getPendingOpCount()));
return removed;
}
@Override
public int getPendingOpCount() {
return onGoingOps.size();
}
@Override
public boolean isBusy() {
return (!this.onGoingOps.isEmpty());
}
@Override
public boolean isOpPending(O operation) {
return onGoingOps.contains(operation);
}
@Override
public List getPendingOpList() {
return Collections.unmodifiableList(onGoingOps);
}
public void onCreate() {
/*
* Nothing to do
*/
}
public void onStart() {
for (AndroidOperationManagerImpl.OperationStore os : this.stored) {
context.registerReceiver(os.receiver, os.filter);
}
}
public void onResume() {
this.active = true;
}
public void onPause() {
this.active = false;
}
public void onStop() {
for (AndroidOperationManagerImpl.OperationStore os : this.stored) {
try {
context.unregisterReceiver(os.receiver);
} catch (Exception e) {
logger.warn(e, "Failure during unregistering reciver. Ignoring it.");
}
}
}
public void onDestroy() {
/*
* Nothing to do
*/
}
public void onActivityCreated(Bundle savedInstanceState) {
/*
* Nothing to do
*/
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy