/******************************************************************************* * Code contributed to the webinos project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Copyright 2011-2012 Paddy Byers * ******************************************************************************/ package org.webinos.android.wrt.channel; import java.util.HashSet; import org.webinos.android.wrt.core.WidgetConfig; import org.webinos.android.wrt.renderer.WebView; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.Messenger; import android.os.RemoteException; import android.util.Log; public class ClientSocket { public static final String SOCKETJS_ASSET = "js/webinossocket.js"; public static final String WEBINOSJS_ASSET = "js/webinos.js"; private static final String TAG = "org.webinos.android.wrt.channel.ClientSocket"; private final WebView webView; private WidgetConfig widgetConfig; private String instanceId; private Session session; private Messenger incomingHandler = null; private HashSet<String> ids = new HashSet<String>(); private static String escapeString(String text) { StringBuffer buf = new StringBuffer(); for(int i = 0; i < text.length(); i++) { char c = text.charAt(i); switch(c) { case '\'': buf.append("\\\'"); break; case '"': buf.append("\\\""); break; case '\\': buf.append("\\\\"); break; case '\n': buf.append("\\n"); break; case '\r': buf.append("\\r"); break; case '\t': buf.append("\\t"); break; default: buf.append(c); } } return buf.toString(); } public ClientSocket(WebView webView, WidgetConfig widgetConfig, String instanceId) { this.webView = webView; this.widgetConfig = widgetConfig; this.instanceId = instanceId; session = Session.getSession(); } public void dispose() { for(String id : ids) closeSocket(Integer.parseInt(id)); } public void openSocket(final int id) { Log.v(TAG, "openSocket()"); session.checkState(); incomingHandler = new Messenger(new Handler() { @Override public void handleMessage(Message msg) { Log.v(TAG, "handleMessage: msg: " + msg.toString()); switch (ProtocolConstants.whatToMsg(msg.what)) { case ProtocolConstants.MSG_DISCONNECT: Log.v(TAG, "IncomingHandler: disconnect"); break; case ProtocolConstants.MSG_DATA: Log.v(TAG, "IncomingHandler: data"); String data = ((Bundle)msg.obj).getString("data"); Log.v(TAG, "IncomingHander: data: " + data); int id = ProtocolConstants.whatToId(msg.what); webView.callScript("WebinosSocket.handleMessage(" + id + ", '" + escapeString(data) + "');"); break; default: super.handleMessage(msg); } Log.v(TAG, "handleMessage: ret"); } }); try { Log.v(TAG, "sending connect message"); Bundle clientDetails = new Bundle(); clientDetails.putString("instanceId", instanceId); clientDetails.putString("installId", widgetConfig.getInstallId()); Message msg = Message.obtain(null, ProtocolConstants.toWhat(ProtocolConstants.MSG_CONNECT, id), clientDetails); session.send(msg, incomingHandler); ids.add(String.valueOf(id)); webView.callScript("WebinosSocket.handleConnect(" + id + ");"); } catch (RemoteException e) { throw new RuntimeException("Exception opening socket", e); } } public void closeSocket(int id) { session.checkState(); try { Message msg = Message.obtain(null, ProtocolConstants.toWhat(ProtocolConstants.MSG_DISCONNECT, id)); session.send(msg, null); } catch (RemoteException e) { throw new RuntimeException("Exception closing socket", e); } } public void send(int id, String message) { session.checkState(); try { Bundle messageBundle = new Bundle(); messageBundle.putString("data", message); Message msg = Message.obtain(null, ProtocolConstants.toWhat(ProtocolConstants.MSG_DATA, id), messageBundle); session.send(msg, null); } catch (RemoteException e) { throw new RuntimeException("Exception sending on socket", e); } } }