/**
*
*/
package ma.car.tishadow.bundle.update;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import ma.car.tishadow.bundle.update.RequestProxy.ForceUpdateRequiredListener;
import ma.car.tishadow.bundle.update.tasks.ApplyBundleUpdateOnlineTask;
import ma.car.tishadow.bundle.update.tasks.BundleUpdateManager;
import ma.car.tishadow.bundle.update.tasks.DefaultBundleUpdateStateListener;
import ma.car.tishadow.bundle.update.tasks.Task;
import ma.car.tishadow.bundle.update.util.TiAppUtil;
import android.util.Log;
/**
* Represents a singleton handler to handle all bundle update request in the FIFO queue.
* @author wei.ding
*/
public class BundleUpdateRequestHandler {
/**
*
*/
private static final String TAG = "BundleUpdateRequestHandler";
private AtomicBoolean handling = new AtomicBoolean(false);
private final LinkedBlockingQueue<RequestTaskEntry> queue;
private final BundleUpdateStateListener stateChangedListener;
private final RequestProxy.ForceUpdateRequiredListener forceUpdateRequiredListener;
private static class Singleton {
public static final BundleUpdateRequestHandler INSTANCE = new BundleUpdateRequestHandler();
}
private BundleUpdateRequestHandler() {
super();
this.queue = new LinkedBlockingQueue<RequestTaskEntry>();
this.stateChangedListener = new DefaultBundleUpdateStateListener();
this.forceUpdateRequiredListener = new RequestProxy.ForceUpdateRequiredListener() {
@Override
public void onForceUpdateRequired() {
queue.clear();
}
};
}
/**
* Gets singleton handler instance.
* @return
*/
public static BundleUpdateRequestHandler getInstance() {
return Singleton.INSTANCE;
}
/**
* Sends a bundle update request into queue.
* @param request
*/
public void sendRequest(RequestProxy request) {
if (request == null) {
throw new NullPointerException("request can not be null.");
}
this.queue.add(new RequestTaskEntry(request, new BundleUpdateManager()));
handleRequest();
}
/**
* Applies pending standby resources online.
* @param request
*/
public void applyPendingUpdateOnline(final RequestProxy request) {
request.setOnBundleUpdateStateChangedListener(new DefaultBundleUpdateStateListener());
new ApplyBundleUpdateOnlineTask().execute(request);
request.setOnBundleUpdateStateChangedListener(null);
}
private void handleRequest() {
if (!handling.compareAndSet(false, true)) {
Log.i(TAG, "There is a request in progress now, will wait for current request be handled.");
return;
}
final RequestTaskEntry entry = this.queue.poll();
if (entry == null) {
Log.i(TAG, "Empty queue, will exit current round process.");
handling.set(false);
return;
}
TiAppUtil.THREAD_POOL.execute(new Runnable() {
@Override
public void run() {
entry.setOnBundleUpdateStateChangedListener(stateChangedListener);
entry.setForceUpdateRequiredListener(forceUpdateRequiredListener);
entry.execute();
entry.setOnBundleUpdateStateChangedListener(null);
entry.setForceUpdateRequiredListener(null);
handling.set(false);
handleRequest();
}
});
}
private static class RequestTaskEntry {
private RequestProxy request;
private Task task;
/**
* @param request
* @param task
*/
public RequestTaskEntry(RequestProxy request, Task task) {
super();
this.request = request;
this.task = task;
}
/**
* @return the request
*/
public RequestProxy getRequest() {
return request;
}
/**
* @return the task
*/
public Task getTask() {
return task;
}
/**
* @param context
* @return
* @see ma.car.tishadow.bundle.update.tasks.Task#execute(ma.car.tishadow.bundle.update.RequestProxy)
*/
public boolean execute() {
return this.getTask().execute(getRequest());
}
/**
* @param onBundleUpdateStateChangedListener
* @see ma.car.tishadow.bundle.update.RequestProxy#setOnBundleUpdateStateChangedListener(ma.car.tishadow.bundle.update.BundleUpdateStateListener)
*/
public void setOnBundleUpdateStateChangedListener(BundleUpdateStateListener onBundleUpdateStateChangedListener) {
request.setOnBundleUpdateStateChangedListener(onBundleUpdateStateChangedListener);
}
/**
* @param forceUpdateRequiredListener
* @see ma.car.tishadow.bundle.update.RequestProxy#setForceUpdateRequiredListener(ma.car.tishadow.bundle.update.RequestProxy.ForceUpdateRequiredListener)
*/
public void setForceUpdateRequiredListener(ForceUpdateRequiredListener forceUpdateRequiredListener) {
request.setForceUpdateRequiredListener(forceUpdateRequiredListener);
}
}
}