Home | History | Annotate | Download | only in event
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.googlecode.android_scripting.event;
     18 
     19 import com.googlecode.android_scripting.Log;
     20 import com.googlecode.android_scripting.SimpleServer;
     21 import com.googlecode.android_scripting.jsonrpc.JsonBuilder;
     22 
     23 import java.io.BufferedReader;
     24 import java.io.IOException;
     25 import java.io.PrintWriter;
     26 import java.net.InetSocketAddress;
     27 import java.net.Socket;
     28 import java.util.Vector;
     29 import java.util.concurrent.CountDownLatch;
     30 
     31 import org.json.JSONException;
     32 
     33 /**
     34  * An Event Forwarding server that forwards events from the rpc queue in realtime to listener
     35  * clients.
     36  *
     37  */
     38 public class EventServer extends SimpleServer implements EventObserver {
     39   private static final Vector<Listener> mListeners = new Vector<Listener>();
     40   private InetSocketAddress address = null;
     41 
     42   public EventServer() {
     43     this(0);
     44   }
     45 
     46   public EventServer(int port) {
     47     address = startAllInterfaces(port);
     48   }
     49 
     50   public InetSocketAddress getAddress() {
     51     return address;
     52   }
     53 
     54   @Override
     55   public void shutdown() {
     56     onEventReceived(new Event("sl4a", "{\"shutdown\": \"event-server\"}"));
     57     for (Listener listener : mListeners) {
     58       mListeners.remove(listener);
     59       listener.lock.countDown();
     60     }
     61     super.shutdown();
     62   }
     63 
     64   @Override
     65   protected void handleConnection(Socket socket) throws IOException {
     66     Log.d("handle event connection.");
     67     Listener l = new Listener(socket);
     68     Log.v("Adding EventServer listener " + socket.getPort());
     69     mListeners.add(l);
     70     // we are running in the socket accept thread
     71     // wait until the event dispatcher gets us the events
     72     // or we die, what ever happens first
     73     try {
     74       l.lock.await();
     75     } catch (InterruptedException e) {
     76       e.printStackTrace();
     77     }
     78     try {
     79       l.sock.close();
     80     } catch (IOException e) {
     81       e.printStackTrace();
     82     }
     83     Log.v("Ending EventServer listener " + socket.getPort());
     84   }
     85 
     86   @Override
     87   public void onEventReceived(Event event) {
     88     Object result = null;
     89     try {
     90       result = JsonBuilder.build(event);
     91     } catch (JSONException e) {
     92       return;
     93     }
     94 
     95     Log.v("EventServer dispatching " + result);
     96 
     97     for (Listener listener : mListeners) {
     98       if (!listener.out.checkError()) {
     99         listener.out.write(result + "\n");
    100         listener.out.flush();
    101       } else {
    102         // let the socket accept thread we're done
    103         mListeners.remove(listener);
    104         listener.lock.countDown();
    105       }
    106     }
    107   }
    108 
    109   private class Listener {
    110     private Socket sock;
    111     private PrintWriter out;
    112     private CountDownLatch lock = new CountDownLatch(1);
    113 
    114     public Listener(Socket l) throws IOException {
    115       sock = l;
    116       out = new PrintWriter(l.getOutputStream(), true);
    117     }
    118   }
    119 
    120   @Override
    121   protected void handleRPCConnection(Socket sock, Integer UID, BufferedReader reader, PrintWriter writer)
    122       throws Exception {
    123   }
    124 }
    125