private void initCamera() {
    SurfaceView cameraSurface = (SurfaceView) findViewById(R.id.surface_camera);
    cameraView_ = new CameraView(cameraSurface);
    cameraView_.setCameraReadyCallback(this);

    overlayView_ = (OverlayView) findViewById(R.id.surface_overlay);
    overlayView_.setOnTouchListener(this);
    overlayView_.setUpdateDoneCallback(this);
  }
        public void onPreviewFrame(byte[] frame, Camera c) {
          if (!inProcessing) {
            inProcessing = true;

            int picWidth = cameraView_.Width();
            int picHeight = cameraView_.Height();
            ByteBuffer bbuffer = ByteBuffer.wrap(frame);
            try {
              bbuffer.get(preFrame, 0, picWidth * picHeight + picWidth * picHeight / 2);

              int numFilled = 0;

              int y = picHeight / 2;
              for (int i = 0; i < PIN_LENGTH; i++) {
                int x =
                    picWidth / 2 + (int) ((i + 0.5f - PIN_LENGTH / 2) * SYMBOL_SPACING * picWidth);
                int p = 0;
                // Take 4 nearby pixels, to filter out noise
                p += preFrame[picWidth * y + x] & 0xFF;
                p += preFrame[picWidth * y + x + 1] & 0xFF;
                p += preFrame[picWidth * (y + 1) + x] & 0xFF;
                p += preFrame[picWidth * (y + 1) + x + 1] & 0xFF;
                p /= 4;
                pinEntered[i] = (p < BRIGHTNESS_THRESHOLD);

                if (pinEntered[i]) numFilled++;
              }
              overlayView_.invalidate();

              if (System.currentTimeMillis() > delay) {
                delay = System.currentTimeMillis() + SEND_DELAY;

                if (sendEnter && numFilled == 0) {
                  sendEnter = false;
                  currentPin++;
                  runOnUiThread(
                      new Runnable() {
                        public void run() {
                          tvMessage2.setText("PIN: " + currentPin);
                        }
                      });
                }

                if (sendEnter && numFilled == PIN_LENGTH) {
                  final String[] cmd = {
                    "/system/bin/sh",
                    "-c",
                    "echo 'echo enter | "
                        + getFilesDir().getAbsolutePath()
                        + "/hid-gadget-test /dev/hidg0 keyboard' | su"
                  };
                  runOnUiThread(
                      new Runnable() {
                        public void run() {
                          tvMessage2.setText("PIN: " + currentPin + " - sending Enter");
                        }
                      });
                  Runtime.getRuntime().exec(cmd).waitFor();
                }

                if (!sendEnter && numFilled == PIN_LENGTH) {
                  sendEnter = true;
                }

                if (!sendEnter && numFilled < PIN_LENGTH) {
                  final int digit =
                      (currentPin / (int) Math.pow(10, PIN_LENGTH - numFilled - 1)) % 10;
                  final int pos = numFilled + 1;
                  final String[] cmd = {
                    "/system/bin/sh",
                    "-c",
                    "echo 'echo "
                        + digit
                        + " | "
                        + getFilesDir().getAbsolutePath()
                        + "/hid-gadget-test /dev/hidg0 keyboard' | su"
                  };
                  runOnUiThread(
                      new Runnable() {
                        public void run() {
                          tvMessage2.setText(
                              "PIN: "
                                  + String.format("%04d", currentPin)
                                  + " - sending digit #"
                                  + pos
                                  + " : "
                                  + digit);
                        }
                      });
                  Runtime.getRuntime().exec(cmd).waitFor();
                }
              }

            } catch (Exception e) {
              e.printStackTrace();
            }

            inProcessing = false;
          }
        }