1 package com.googlecode.android_scripting.service; 2 3 import android.annotation.TargetApi; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.HandlerThread; 7 import android.os.Message; 8 import android.os.RemoteException; 9 10 import com.googlecode.android_scripting.Log; 11 import com.googlecode.android_scripting.jsonrpc.JsonRpcResult; 12 import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager; 13 import com.googlecode.android_scripting.jsonrpc.RpcReceiverManagerFactory; 14 import com.googlecode.android_scripting.rpc.MethodDescriptor; 15 16 import org.json.JSONException; 17 import org.json.JSONObject; 18 19 /** 20 * Class responsible for Handling messages that came through the FacadeService 21 * interface. 22 * <br> 23 * Please refer to {@link FacadeService} for details on how to use. 24 */ 25 @TargetApi(3) 26 public class MessageHandler extends Handler { 27 28 private static final int SL4A_ACTION = 0; 29 private static final int DEFAULT_SENDING_ID = 0; 30 31 // Android sets this to -1 when the message is not sent by a Messenger. 32 // see http://developer.android.com/reference/android/os/Message.html#sendingUid 33 private static final int DEFAULT_UNSET_SENDING_ID = 1; 34 35 // Keys for the Bundles. 36 private static final String SL4A_METHOD = "sl4aMethod"; 37 private static final String SL4A_RESULT = "sl4aResult"; 38 39 private final RpcReceiverManagerFactory mRpcReceiverManagerFactory; 40 41 public MessageHandler(HandlerThread handlerThread, 42 RpcReceiverManagerFactory rpcReceiverManagerFactory) { 43 super(handlerThread.getLooper()); 44 this.mRpcReceiverManagerFactory = rpcReceiverManagerFactory; 45 } 46 47 /** 48 * Handles messages for the service. It does this via the same mechanism used 49 * for RPCs through RpcManagers. 50 * 51 * @param message The message that contains the method and parameters to 52 * execute. 53 */ 54 @Override 55 public void handleMessage(Message message) { 56 Log.d("Handling Remote request"); 57 int senderId = message.sendingUid == DEFAULT_UNSET_SENDING_ID ? 58 DEFAULT_SENDING_ID : message.sendingUid; 59 if (message.what == SL4A_ACTION) { 60 RpcReceiverManager receiverManager; 61 if (mRpcReceiverManagerFactory.getRpcReceiverManagers().containsKey(senderId)) { 62 receiverManager = mRpcReceiverManagerFactory.getRpcReceiverManagers().get(senderId); 63 } else { 64 receiverManager = mRpcReceiverManagerFactory.create(senderId); 65 } 66 Bundle sl4aRequest = message.getData(); 67 String method = sl4aRequest.getString(SL4A_METHOD); 68 if (method == null || "".equals(method)) { 69 Log.e("No SL4A method specified on the Bundle. Specify one with " 70 + SL4A_METHOD); 71 return; 72 } 73 MethodDescriptor rpc = receiverManager.getMethodDescriptor(method); 74 if (rpc == null) { 75 Log.e("Unknown RPC: \"" + method + "\""); 76 return; 77 } 78 try { 79 Log.d("Invoking method " + rpc.getName()); 80 Object result = rpc.invoke(receiverManager, sl4aRequest); 81 // Only return a result if we were passed a Messenger. Otherwise assume 82 // client did not care for the response. 83 if (message.replyTo != null) { 84 Message reply = Message.obtain(); 85 Bundle sl4aResponse = new Bundle(); 86 putResult(senderId, result, sl4aResponse); 87 reply.setData(sl4aResponse); 88 message.replyTo.send(reply); 89 } 90 } catch (RemoteException e) { 91 Log.e("Could not send reply back to client", e); 92 } catch (Throwable t) { 93 Log.e("Exception while executing sl4a method", t); 94 } 95 } 96 } 97 98 private void putResult(int id, Object result, Bundle reply) { 99 JSONObject json; 100 try { 101 if (result instanceof Throwable) { 102 json = JsonRpcResult.error(id, (Throwable) result); 103 } else { 104 json = JsonRpcResult.result(id, result); 105 } 106 } catch (JSONException e) { 107 // There was an error converting the result to JSON. This shouldn't 108 // happen normally. 109 Log.e("Caught exception when filling JSON result.", e); 110 reply.putString(SL4A_RESULT, e.toString()); 111 return; 112 } 113 Log.d("Returning result: " + json.toString()); 114 reply.putString(SL4A_RESULT, json.toString()); 115 } 116 } 117