package com.xtreme.wall.service.amqp; import java.io.IOException; import java.util.UUID; import android.app.Service; import android.bluetooth.BluetoothClass.Device; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.Point; import android.os.AsyncTask; import android.os.Build; import android.os.IBinder; import android.view.Display; import android.view.WindowManager; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.rabbitmq.client.AMQP.BasicProperties; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Envelope; import com.rabbitmq.client.QueueingConsumer; import com.xtreme.utils.Logger; import com.xtreme.wall.service.amqp.AmqpConnection.AmqpConnectionListener; import com.xtreme.wall.service.amqp.AmqpServiceBinder.PublishListener; import com.xtreme.wall.service.utils.ScreenUtils; import com.xtreme.wall.shared.amqp.AmqpPublishListener; import com.xtremelabs.devicewall.protocol.AmqpConstants; import com.xtremelabs.devicewall.protocol.Protocol; import com.xtremelabs.devicewall.protocol.gamecontrol.GameControlDeserializer; import com.xtremelabs.devicewall.protocol.gamecontrol.GameControlMessageType; import com.xtremelabs.devicewall.protocol.gamecontrol.response.ServerStartResponse; import com.xtremelabs.devicewall.protocol.identifier.IdentifierMessageType; import com.xtremelabs.devicewall.protocol.identifier.request.MobileServerIdentifierRequest; import com.xtremelabs.devicewall.protocol.identifier.response.ServerIdentifierResponse; public class AmqpService extends Service { private AmqpServiceBinder mAmqpServiceBinder; private AmqpConnection mConnection; private AmqpAutoConnectUtil mConnectionUtil; private Long mId; private static Gson sGameControlGson; static { final GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Protocol.class, new GameControlDeserializer()); sGameControlGson = builder.create(); } public static enum AmqpListenerType { passive, active } @Override public void onCreate() { super.onCreate(); Logger.setup(true, "AmqpService"); Logger.debug("onCreate"); final Intent startServiceIntent = new Intent(getApplicationContext(), AmqpService.class); startService(startServiceIntent); mAmqpServiceBinder = new AmqpServiceBinder(this, new PublishListener() { @Override public void onPublishToServer(final String json, final AmqpPublishListener listener) { mConnection.publish(AmqpConstants.SERVER_EXCHANGE, AmqpConstants.SERVER_ROUTING_KEY, null, json.getBytes(), listener); } @Override public void onPublishToAll(final String json, final AmqpPublishListener listener) { mConnection.publish(AmqpConstants.SERVER_EXCHANGE, AmqpConstants.CLIENT_ROUTING_KEY, null, json.getBytes(), listener); } }); mConnection = new AmqpConnection(new AmqpConnectionListener() { @Override public void onAmqpDisconnected() { mAmqpServiceBinder.onDisconnected(); mConnectionUtil.autoConnect(); } @Override public void onAmqpConnected() { initializeConsumer(); } }); mConnectionUtil = new AmqpAutoConnectUtil(mConnection); mConnectionUtil.autoConnect(); } @Override public IBinder onBind(Intent intent) { Logger.debug("onBond"); return mAmqpServiceBinder; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Logger.debug("onStartCommand"); return Service.START_STICKY; } private void initializeConsumer() { Logger.debug("initializeConsumer"); new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { Logger.debug("doInBackground"); final Channel channel = mConnection.getChannel(); try { String serial = Build.SERIAL; if (serial == null || serial.isEmpty()) { SharedPreferences sharedPreferences = getSharedPreferences("amqp_service", Context.MODE_PRIVATE); serial = sharedPreferences.getString("uuid", UUID.randomUUID().toString()); sharedPreferences.edit().putString("uuid", serial).commit(); } Logger.debug("serial: " + serial); final String queueName = channel.queueDeclare(serial, false, true, false, null).getQueue(); Logger.debug("queueName: "+ queueName); channel.queueBind(queueName, AmqpConstants.SERVER_EXCHANGE, AmqpConstants.CLIENT_ROUTING_KEY); Logger.d("bound to: " + AmqpConstants.CLIENT_ROUTING_KEY); channel.queueBind(queueName, AmqpConstants.SERVER_EXCHANGE, serial); Logger.d("bound to: " + serial); if (mId != null) { channel.queueBind(queueName, AmqpConstants.SERVER_EXCHANGE, Long.toString(mId)); } channel.basicConsume(queueName, new QueueingConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, BasicProperties properties, byte[] body) throws IOException { final String message = new String(body); Logger.debug("message: " + message); channel.basicAck(envelope.getDeliveryTag(), true); Protocol protocol = sGameControlGson.fromJson(message, Protocol.class); final GameControlMessageType gameControlMesseageType = GameControlMessageType.getModelType(protocol.getType()); switch (gameControlMesseageType) { case SERVER_START: final ServerStartResponse serverStartResponse = (ServerStartResponse) protocol.getData(); if (AmqpConstants.MEMORY_SERVER_APP_NAME.equals(serverStartResponse.getApp())) { final Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setComponent(new ComponentName("com.xtremelabs.devicewallmemorygame", "com.xtremelabs.devicewallmemorygame.MainActivity")); startActivity(intent); } else if (AmqpConstants.IMAGE_SERVER_APP_NAME.equals(serverStartResponse.getApp())) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setComponent(new ComponentName("com.xtremelabs.devicewallimageapp", "com.xtremelabs.devicewallimageapp.ImageActivity")); startActivity(intent); } else if (AmqpConstants.IDENTIFIER_SERVER_APP_NAME.equals(serverStartResponse.getApp())) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setComponent(new ComponentName("com.xtremelabs.devicewallidentifierapp", "com.xtremelabs.devicewallidentifierapp.activities.IdentifierActivity")); startActivity(intent); } default: } protocol = AmqpConstants.sIdentifierGson.fromJson(message, Protocol.class); if (protocol == null) { mAmqpServiceBinder.onMessageReceived(message); return; } final IdentifierMessageType messageType = IdentifierMessageType.getModelType(protocol.getType()); switch (messageType) { case SERVER_IDENTIFIER_RESPONSE: final ServerIdentifierResponse serverIdentifierResponse = (ServerIdentifierResponse) protocol.getData(); final Long id = serverIdentifierResponse.getId(); if (id != null) channel.queueBind(queueName, AmqpConstants.SERVER_EXCHANGE, Long.toString(id)); mAmqpServiceBinder.setId(id); break; default: mAmqpServiceBinder.onMessageReceived(message); } } }); final Boolean isTablet = ScreenUtils.isTablet(getApplicationContext()); final WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); final Display display = wm.getDefaultDisplay(); final Point size = new Point(); // display.getSize(size); final int width = size.x; final int height = size.y; final MobileServerIdentifierRequest mobileServerIdentifierRequest = new MobileServerIdentifierRequest(queueName, isTablet, width, height, serial); final Protocol protocol = new Protocol(null, IdentifierMessageType.MOBILE_SERVER_IDENTIFIER_REQUEST.toString(), mobileServerIdentifierRequest); Logger.debug("protocol: " + protocol.toJson().toString()); channel.basicPublish(AmqpConstants.SERVER_EXCHANGE, AmqpConstants.SERVER_ROUTING_KEY, null, protocol.toJson().toString().getBytes()); return queueName; } catch (Exception e) { e.printStackTrace(); mConnection.close(); mConnectionUtil.autoConnect(); return null; } } @Override protected void onPostExecute(String queueName) { if (queueName != null) { mAmqpServiceBinder.onConnected(queueName); } else { mConnectionUtil.autoConnect(); } } }.execute(); } public void setId(Long id) { mId = id; } public Long getId() { return mId; } }