package org.jboss.aerogear.android.impl.simplepush; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; import android.os.IBinder; import android.util.Log; import java.net.URI; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicReference; import org.jboss.aerogear.android.Callback; public class SimplePushService extends Service { private int serviceId; private static final ExecutorService EXECUTOR = Executors.newCachedThreadPool(); private SimplePushWebsocketClient client; private static final String TAG = SimplePushService.class.getSimpleName(); private CountDownLatch connectionLatch = new CountDownLatch(1); private Handler handler; @Override public int onStartCommand(Intent intent, int flags, int startId) { this.serviceId = startId; synchronized (this) { if (handler == null) { HandlerThread thread = new HandlerThread(TAG); thread.start(); handler = new Handler(thread.getLooper()); } } if (intent == null) { handleRestart(); } else { startNewWebSocket(); } return START_STICKY; } @Override public IBinder onBind(Intent intent) { return new SimplePushBinder(); } private void handleRestart() { throw new UnsupportedOperationException("Not supported yet."); } private void startNewWebSocket() { client = new SimplePushWebsocketClient(URI.create("wss://push-coffeeregister.rhcloud.com:8443/simplepush/websocket")); client.connect(connectionLatch); } public Future<PushChannel> register(String category) throws TimeoutException, InterruptedException { final CountDownLatch registerLatch = new CountDownLatch(1); final AtomicReference<PushChannel> pushChannelReference = new AtomicReference<PushChannel>(); if (!connectionLatch.await(9000, TimeUnit.SECONDS)) { throw new IllegalStateException("Could not register the channel."); } client.registerChannel(new Callback<PushChannel>() { @Override public void onSuccess(PushChannel data) { pushChannelReference.set(data); registerLatch.countDown(); } @Override public void onFailure(Exception ex) { Log.e(TAG, ex.getMessage(), ex); registerLatch.countDown(); } }); return EXECUTOR.submit(new Callable<PushChannel>() { @Override public PushChannel call() throws Exception { try { if (!registerLatch.await(3000, TimeUnit.SECONDS)) { throw new TimeoutException(); } } catch (InterruptedException ex) { Log.e(TAG, ex.getMessage(), ex); } PushChannel urlResult = pushChannelReference.get(); if (urlResult == null) { throw new IllegalStateException("Could not register the channel."); } return urlResult; } }); } public class SimplePushBinder extends Binder { public SimplePushService getService() { return SimplePushService.this; } } }