@Override
  protected void setUp() throws Exception {
    super.setUp();

    httpServer = new AsyncHttpServer();
    httpServer.setErrorCallback(
        new CompletedCallback() {
          @Override
          public void onCompleted(Exception ex) {
            fail();
          }
        });
    httpServer.listen(AsyncServer.getDefault(), 5000);

    httpServer.websocket(
        "/ws",
        new WebSocketRequestCallback() {
          @Override
          public void onConnected(final WebSocket webSocket, RequestHeaders headers) {
            webSocket.setStringCallback(
                new StringCallback() {
                  @Override
                  public void onStringAvailable(String s) {
                    webSocket.send(s);
                  }
                });
          }
        });
  }
  /** Main Entry Point of the server code. Create a WebSocket server and start the encoder. */
  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent != null && intent.getAction() == "STOP") {
      if (encoder != null) encoder.signalEndOfInputStream();
      server.stop();
      server = null;
      stopForeground(true);
      stopSelf();
    }
    if (server == null && intent.getAction().equals("START")) {
      preferences = PreferenceManager.getDefaultSharedPreferences(this);
      LOCAL_DEBUG = preferences.getBoolean("local_debugging", true);
      DisplayMetrics dm = new DisplayMetrics();
      Display mDisplay =
          ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
      mDisplay.getMetrics(dm);
      deviceWidth = dm.widthPixels;
      deviceHeight = dm.heightPixels;
      float resolutionRatio =
          Float.parseFloat(preferences.getString(SettingsActivity.KEY_RESOLUTION_PREF, "0.25"));
      mDisplay.getRealSize(resolution);
      resolution.x = (int) (resolution.x * resolutionRatio);
      resolution.y = (int) (resolution.y * resolutionRatio);

      if (!LOCAL_DEBUG) {
        server = new AsyncHttpServer();
        server.websocket("/", null, websocketCallback);
        serverPort =
            Integer.parseInt(preferences.getString(SettingsActivity.KEY_PORT_PREF, "6060"));
        bitrateRatio =
            Float.parseFloat(preferences.getString(SettingsActivity.KEY_BITRATE_PREF, "1"));
        updateNotification("Streaming is live at");
        server.listen(serverPort);
      } else {
        final WindowManager.LayoutParams params =
            new WindowManager.LayoutParams(
                WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                    | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);

        params.gravity = Gravity.TOP | Gravity.LEFT;
        params.height = WindowManager.LayoutParams.WRAP_CONTENT;
        params.width = WindowManager.LayoutParams.WRAP_CONTENT;

        WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
        LayoutInflater inflater =
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        videoWindow = (VideoWindow) inflater.inflate(R.layout.video_window, null);
        windowManager.addView(videoWindow, params);
        videoWindow.inflateSurfaceView();

        if (encoderThread == null) {
          encoderThread = new Thread(new EncoderWorker(), "Encoder Thread");
          encoderThread.start();
        }
      }

      mHandler = new Handler();
    }
    return START_NOT_STICKY;
  }
  @Override
  protected void tearDown() throws Exception {
    super.tearDown();

    httpServer.stop();
  }