package org.apache.bcel.classfile;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public final class LineNumberTable extends Attribute {

    private static final long serialVersionUID = -6967221519632128904L;

    private int line_number_table_length;

    private LineNumber[] line_number_table;

    public LineNumberTable(LineNumberTable c) {
        this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
    }

    public LineNumberTable(int name_index, int length, LineNumber[] line_number_table, ConstantPool constant_pool) {
        super((byte) 4, name_index, length, constant_pool);
        setLineNumberTable(line_number_table);
    }

    LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
        this(name_index, length, (LineNumber[]) null, constant_pool);
        line_number_table_length = file.readUnsignedShort();
        line_number_table = new LineNumber[line_number_table_length];
        for (int i = 0; i < line_number_table_length; i++) line_number_table[i] = new LineNumber(file);
    }

    @Override
    public void accept(Visitor v) {
        v.visitLineNumberTable(this);
    }

    @Override
    public final void dump(DataOutputStream file) throws IOException {
        super.dump(file);
        file.writeShort(line_number_table_length);
        for (int i = 0; i < line_number_table_length; i++) line_number_table[i].dump(file);
    }

    public final LineNumber[] getLineNumberTable() {
        return line_number_table;
    }

    public final void setLineNumberTable(LineNumber[] line_number_table) {
        this.line_number_table = line_number_table;
        line_number_table_length = line_number_table == null ? 0 : line_number_table.length;
    }

    @Override
    public final String toString() {
        final StringBuilder buf = new StringBuilder();
        final StringBuilder line = new StringBuilder();
        final String newLine = System.getProperty("line.separator", "\n");
        for (int i = 0; i < line_number_table_length; i++) {
            line.append(line_number_table[i].toString());
            if (i < line_number_table_length - 1)
                line.append(", ");
            if (line.length() > 72) {
                line.append(newLine);
                buf.append(line.toString());
                line.setLength(0);
            }
        }
        buf.append(line);
        return buf.toString();
    }

    public int getSourceLine(int pos) {
        int l = 0;
        int r = line_number_table_length - 1;
        if (r < 0)
            return -1;
        int min_index = -1;
        int min = -1;
        do {
            final int i = (l + r) / 2;
            final int j = line_number_table[i].getStartPC();
            if (j == pos)
                return line_number_table[i].getLineNumber();
            if (pos < j)
                r = i - 1;
            else
                l = i + 1;
            if (j < pos && j > min) {
                min = j;
                min_index = i;
            }
        } while (l <= r);
        if (min_index < 0)
            return -1;
        return line_number_table[min_index].getLineNumber();
    }

    @Override
    public Attribute copy(ConstantPool _constant_pool) {
        final LineNumberTable c = (LineNumberTable) clone();
        c.line_number_table = new LineNumber[line_number_table_length];
        for (int i = 0; i < line_number_table_length; i++) c.line_number_table[i] = line_number_table[i].copy();
        c.constant_pool = _constant_pool;
        return c;
    }

    public final int getTableLength() {
        return


for (int i = 0; i < line_number_table_length; i++) {
            line.append(line_number_table[i].toString());
            if (i < line_number_table_length - 1)
                line.append(", ");
            if (line.length() > 72) {
                line.append(newLine);
                buf.append(line.toString());
                line.setLength(0);
            }
        }

package org.apache.bcel.classfile;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

public final class LineNumberTable extends Attribute {

    private static final long serialVersionUID = -6967221519632128904L;

    private int line_number_table_length;

    private LineNumber[] line_number_table;

    public LineNumberTable(LineNumberTable c) {
        this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
    }

    public LineNumberTable(int name_index, int length, LineNumber[] line_number_table, ConstantPool constant_pool) {
        super((byte) 4, name_index, length, constant_pool);
        setLineNumberTable(line_number_table);
    }

    LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
        this(name_index, length, (LineNumber[]) null, constant_pool);
        line_number_table_length = file.readUnsignedShort();
        line_number_table = new LineNumber[line_number_table_length];
        for (int i = 0; i < line_number_table_length; i++) line_number_table[i] = new LineNumber(file);
    }

    @Override
    public void accept(Visitor v) {
        v.visitLineNumberTable(this);
    }

    @Override
    public final void dump(DataOutputStream file) throws IOException {
        super.dump(file);
        file.writeShort(line_number_table_length);
        for (int i = 0; i < line_number_table_length; i++) line_number_table[i].dump(file);
    }

    public final LineNumber[] getLineNumberTable() {
        return line_number_table;
    }

    public final void setLineNumberTable(LineNumber[] line_number_table) {
        this.line_number_table = line_number_table;
        line_number_table_length = line_number_table == null ? 0 : line_number_table.length;
    }

    @Override
    public final String toString() {
        final StringBuilder buf = new StringBuilder();
        final StringBuilder line = new StringBuilder();
        final String newLine = System.getProperty("line.separator", "\n");

        buf.append(line);
        return buf.toString();
    }

    public int getSourceLine(int pos) {
        int l = 0;
        int r = line_number_table_length - 1;
        if (r < 0)
            return -1;
        int min_index = -1;
        int min = -1;
        do {
            final int i = (l + r) / 2;
            final int j = line_number_table[i].getStartPC();
            if (j == pos)
                return line_number_table[i].getLineNumber();
            if (pos < j)
                r = i - 1;
            else
                l = i + 1;
            if (j < pos && j > min) {
                min = j;
                min_index = i;
            }
        } while (l <= r);
        if (min_index < 0)
            return -1;
        return line_number_table[min_index].getLineNumber();
    }

    @Override
    public Attribute copy(ConstantPool _constant_pool) {
        final LineNumberTable c = (LineNumberTable) clone();
        c.line_number_table = new LineNumber[line_number_table_length];
        for (int i = 0; i < line_number_table_length; i++) c.line_number_table[i] = line_number_table[i].copy();
        c.constant_pool = _constant_pool;
        return c;
    }

    public final int getTableLength() {
        return line_number_table_length;
    }
}


@Override
                public void run()

package org.apache.inlong.tubemq.corerpc.benchemark;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.inlong.tubemq.corebase.cluster.BrokerInfo;
import org.apache.inlong.tubemq.corerpc.RpcConfig;
import org.apache.inlong.tubemq.corerpc.RpcConstants;
import org.apache.inlong.tubemq.corerpc.RpcServiceFactory;
import org.apache.inlong.tubemq.corerpc.netty.NettyClientFactory;

public class RcpService4BenchmarkClient {

    private final ExecutorService executorService = Executors.newCachedThreadPool();

    private final String targetHost;

    private final int targetPort;

    private final RpcServiceFactory rpcServiceFactory;

    private final NettyClientFactory clientFactory = new NettyClientFactory();

    private SimpleService simpleService;

    private int threadNum = 10;

    private int invokeTimes = 1000000;

    public RcpService4BenchmarkClient(String targetHost, int targetPort, int threadNum, int invokeTimes) {
        this.targetHost = targetHost;
        this.targetPort = targetPort;
        this.threadNum = threadNum;
        this.invokeTimes = invokeTimes;
        RpcConfig config = new RpcConfig();
        config.put(RpcConstants.RPC_CODEC, 6);
        config.put(RpcConstants.CONNECT_TIMEOUT, 3000);
        config.put(RpcConstants.REQUEST_TIMEOUT, 10000);
        clientFactory.configure(config);
        rpcServiceFactory = new RpcServiceFactory(clientFactory);
        BrokerInfo brokerInfo = new BrokerInfo(1, targetHost, targetPort);
        this.simpleService = rpcServiceFactory.getService(SimpleService.class, brokerInfo, config);
    }

    public static void main(String[] args) throws Exception {
        new RcpService4BenchmarkClient("127.0.0.1", 8088, 10, 100000).start();
    }

    public void start() throws Exception {
        for (int i = 0; i < threadNum; i++) {
            executorService.submit(new Runnable() {

{
                    long startTime = System.currentTimeMillis();
                    for (int j = 0; j < invokeTimes; j++) {
                        simpleService.echo("This is a test.");
                    }
                    System.out.println(Thread.currentThread().getName() + " execute " + invokeTimes);
                    long endTime = System.currentTimeMillis() - startTime;
                    System.out.println("cost time:" + endTime + " ms");
                }
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }
}


package org.apache.inlong.tubemq.corerpc.benchemark;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.inlong.tubemq.corebase.cluster.BrokerInfo;
import org.apache.inlong.tubemq.corerpc.RpcConfig;
import org.apache.inlong.tubemq.corerpc.RpcConstants;
import org.apache.inlong.tubemq.corerpc.RpcServiceFactory;
import org.apache.inlong.tubemq.corerpc.netty.NettyClientFactory;

public class RcpService4BenchmarkClient {

    private final ExecutorService executorService = Executors.newCachedThreadPool();

    private final String targetHost;

    private final int targetPort;

    private final RpcServiceFactory rpcServiceFactory;

    private final NettyClientFactory clientFactory = new NettyClientFactory();

    private SimpleService simpleService;

    private int threadNum = 10;

    private int invokeTimes = 1000000;

    public RcpService4BenchmarkClient(String targetHost, int targetPort, int threadNum, int invokeTimes) {
        this.targetHost = targetHost;
        this.targetPort = targetPort;
        this.threadNum = threadNum;
        this.invokeTimes = invokeTimes;
        RpcConfig config = new RpcConfig();
        config.put(RpcConstants.RPC_CODEC, 6);
        config.put(RpcConstants.CONNECT_TIMEOUT, 3000);
        config.put(RpcConstants.REQUEST_TIMEOUT, 10000);
        clientFactory.configure(config);
        rpcServiceFactory = new RpcServiceFactory(clientFactory);
        BrokerInfo brokerInfo = new BrokerInfo(1, targetHost, targetPort);
        this.simpleService = rpcServiceFactory.getService(SimpleService.class, brokerInfo, config);
    }

    public static void main(String[] args) throws Exception

    public void start() throws Exception {
        for (int i = 0; i < threadNum; i++) {
            executorService.submit(new Runnable() {

                @Override
                public void run() {
                    long startTime = System.currentTimeMillis();
                    for (int j = 0; j < invokeTimes; j++) {
                        simpleService.echo("This is a test.");
                    }
                    System.out.println(Thread.currentThread().getName() + " execute " + invokeTimes);
                    long endTime = System.currentTimeMillis() - startTime;
                    System.out.println("cost time:" + endTime + " ms");
                }
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }
}


package org.apache.inlong.tubemq.corerpc.benchemark;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.inlong.tubemq.corebase.cluster.BrokerInfo;
import org.apache.inlong.tubemq.corerpc.RpcConfig;
import org.apache.inlong.tubemq.corerpc.RpcConstants;
import org.apache.inlong.tubemq.corerpc.RpcServiceFactory;
import org.apache.inlong.tubemq.corerpc.netty.NettyClientFactory;

public class RcpService4BenchmarkClient {

    private final ExecutorService executorService = Executors.newCachedThreadPool();

    private final String targetHost;

    private final int targetPort;

    private final RpcServiceFactory rpcServiceFactory;

    private final NettyClientFactory clientFactory = new NettyClientFactory();

    private SimpleService simpleService;

    private int threadNum = 10;

    private int invokeTimes = 1000000;

    public RcpService4BenchmarkClient(String targetHost, int targetPort, int threadNum, int invokeTimes) {
        this.targetHost = targetHost;
        this.targetPort = targetPort;
        this.threadNum = threadNum;
        this.invokeTimes = invokeTimes;
        RpcConfig config = new RpcConfig();
        config.put(RpcConstants.RPC_CODEC, 6);
        config.put(RpcConstants.CONNECT_TIMEOUT, 3000);
        config.put(RpcConstants.REQUEST_TIMEOUT, 10000);
        clientFactory.configure(config);
        rpcServiceFactory = new RpcServiceFactory(clientFactory);
        BrokerInfo brokerInfo = new BrokerInfo(1, targetHost, targetPort);
        this.simpleService = rpcServiceFactory.getService(SimpleService.class, brokerInfo, config);
    }

    public static void main(String[] args) throws Exception {
        new RcpService4BenchmarkClient("127.0.0.1", 8088, 10, 100000).start();
    }

    public void start() throws Exception {
        for (int i = 0; i < threadNum; i++) {
            executorService.submit(new Runnable() {

                @Override
                public void run() {
                    long startTime = System.currentTimeMillis();
                    for (int j = 0; j < invokeTimes; j++) {
                        simpleService.echo("This is a test.");
                    }
                    System.out.println(Thread.currentThread().getName() + " execute " + invokeTimes);
                    long endTime = System.cur

                    System.out.println("cost time:" + endTime + " ms");
                }
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }
}


for (int j = 0; j < invokeTimes; j++) {
                        simpleService.echo("This is a test.");
                    }

package org.apache.inlong.tubemq.corerpc.benchemark;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.apache.inlong.tubemq.corebase.cluster.BrokerInfo;
import org.apache.inlong.tubemq.corerpc.RpcConfig;
import org.apache.inlong.tubemq.corerpc.RpcConstants;
import org.apache.inlong.tubemq.corerpc.RpcServiceFactory;
import org.apache.inlong.tubemq.corerpc.netty.NettyClientFactory;

public class RcpService4BenchmarkClient {

    private final ExecutorService executorService = Executors.newCachedThreadPool();

    private final String targetHost;

    private final int targetPort;

    private final RpcServiceFactory rpcServiceFactory;

    private final NettyClientFactory clientFactory = new NettyClientFactory();

    private SimpleService simpleService;

    private int threadNum = 10;

    private int invokeTimes = 1000000;

    public RcpService4BenchmarkClient(String targetHost, int targetPort, int threadNum, int invokeTimes) {
        this.targetHost = targetHost;
        this.targetPort = targetPort;
        this.threadNum = threadNum;
        this.invokeTimes = invokeTimes;
        RpcConfig config = new RpcConfig();
        config.put(RpcConstants.RPC_CODEC, 6);
        config.put(RpcConstants.CONNECT_TIMEOUT, 3000);
        config.put(RpcConstants.REQUEST_TIMEOUT, 10000);
        clientFactory.configure(config);
        rpcServiceFactory = new RpcServiceFactory(clientFactory);
        BrokerInfo brokerInfo = new BrokerInfo(1, targetHost, targetPort);
        this.simpleService = rpcServiceFactory.getService(SimpleService.class, brokerInfo, config);
    }

    public static void main(String[] args) throws Exception {
        new RcpService4BenchmarkClient("127.0.0.1", 8088, 10, 100000).start();
    }

    public void start() throws Exception {
        for (int i = 0; i < threadNum; i++) {
            executorService.submit(new Runnable() {

                @Override
                public void run() {
                    long startTime = System.currentTimeMillis();

                    System.out.println(Thread.currentThread().getName() + " execute " + invokeTimes);
                    long endTime = System.currentTimeMillis() - startTime;
                    System.out.println("cost time:" + endTime + " ms");
                }
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
    }
}


package org.apache.flink.runtime.leaderelection;

import java.util.UUID;

/**
 * Interface which has to be implemented to take part in the leader election process of the {@link
 * LeaderElectionService}.
 */
public interface LeaderContender {

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon selecting this
     * instance as the new leader. The method is called with the new leader session ID.
     *
     * @param leaderSessionID New leader session ID
     */
    void grantLeadership(UUID leaderSessionID);

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon revoking the
     * leadership of a former leader. This might happen in case that multiple contenders have been
     * granted leadership.
     */
    void revokeLeadership();

    /**
     * Callback method which is called by {@link LeaderElectionService} in case of an error in the
     * service thread.
     *
     * @param exception Caught exception
     */
    void handleError(Exception exception);

    /**
     * Returns the description of the {@link LeaderContender} for logging purposes.
     *
     * @return Description of this contender.
     */

{
        return "LeaderContender: " + getClass().getSimpleName();
    }
}


{
        return "LeaderContender: " + getClass().getSimpleName();
    }

package org.apache.flink.runtime.leaderelection;

import java.util.UUID;

/**
 * Interface which has to be implemented to take part in the leader election process of the {@link
 * LeaderElectionService}.
 */
public interface LeaderContender {

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon selecting this
     * instance as the new leader. The method is called with the new leader session ID.
     *
     * @param leaderSessionID New leader session ID
     */
    void grantLeadership(UUID leaderSessionID);

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon revoking the
     * leadership of a former leader. This might happen in case that multiple contenders have been
     * granted leadership.
     */
    void revokeLeadership();

    /**
     * Callback method which is called by {@link LeaderElectionService} in case of an error in the
     * service thread.
     *
     * @param exception Caught exception
     */
    void handleError(Exception exception);

    /**
     * Returns the description of the {@link LeaderContender} for logging purposes.
     *
     * @return Description of this contender.
     */
    default String getDescription()


package org.apache.flink.runtime.leaderelection;

import java.util.UUID;

/**
 * Interface which has to be implemented to take part in the leader election process of the {@link
 * LeaderElectionService}.
 */
public interface LeaderContender {

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon selecting this
     * instance as the new leader. The method is called with the new leader session ID.
     *
     * @param leaderSessionID New leader session ID
     */
    void grantLeadership(UUID leaderSessionID);

    /**
     * Callback method which is called by the {@link LeaderElectionService} upon revoking the
     * leadership of a former leader. This might happen in case that multiple contenders have been
     * granted leadership.
     */
    void revokeLeadership();

    /**
     * Callback method which is called by {@link LeaderElectionService} in case of an error in the
     * service thread.
     *
     * @param exception Caught exception
     */
    void handleError(Exception exception);

    /**
     * Returns the description of the {@link LeaderContender} for logging purposes.
     *
     * @return Description of this contender.
     */
    default String getDescription() {
        return "LeaderContender: " + getClass().getSimp


default String getDescription() {
        return "LeaderContender: " + getClass().getSimpleName();
    }


package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIsFrontCamera);
    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }
        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera() {
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */

{
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */
    private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }
        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}


{
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIsFrontCamera);
    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }
        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera()

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */
    private void hidePictureTaken() {
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */
    private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }
        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}


package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIs

    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }
        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera() {
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */
    private void hidePictureTaken() {
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */
    private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }
        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}


private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIsFrontCamera);
    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }
        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera() {
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */
    private void hidePictureTaken() {
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {
            switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }
        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}


switch(event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:
                    mCamera.autoFocus(mAutoFocusCallback);
                    return false;
            }

package com.randomlytyping.camera;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;

/**
 * Created by Huyen Tue Dao on 5/13/14.
 */
public class CameraAreaActivity extends Activity implements View.OnClickListener, View.OnTouchListener, Preview.PreviewListener {

    /**
     * ID value for a particular camera (front or back) that was not found.
     */
    private static final int NO_CAMERA = -1;

    /**
     * Whether the currently open camera is the front-facing camera.
     */
    private static final String STATE_IS_FRONT_CAMERA = "isFrontCamera";

    @SuppressWarnings("unused")
    private static final String TAG = "CameraAreaActivity";

    // Views
    private TextView mErrorTextView;

    private ImageView mPictureView;

    private ImageButton mCaptureButton;

    private ImageButton mSwitchButton;

    private Preview mPreview;

    // Camera fields
    private Camera mCamera;

    private boolean mIsFrontCamera;

    private int mBackCameraId;

    private int mFrontCameraId;

    // Threading/runnables
    private long mHidePictureDelay;

    private Handler mHandler;

    private Runnable mHidePictureRunnable = new Runnable() {

        @Override
        public void run() {
            hidePictureTaken();
        }
    };

    // Activity lifecycle
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_area);
        // Grab reference to the TextView for display errors.
        mErrorTextView = (TextView) findViewById(R.id.error_text);
        // Grab references to the picture-taking-related views.
        mPictureView = (ImageView) findViewById(R.id.picture_taken);
        mCaptureButton = (ImageButton) findViewById(R.id.capture_button);
        // Grab references to camera-switching-related views.
        mSwitchButton = (ImageButton) findViewById(R.id.switch_button);
        // Grab reference to the preview.
        mPreview = (Preview) findViewById(R.id.preview);
        mPreview.setListener(this);
        /*
            If the device actually has a camera, set up the surface holder.
            Otherwise, display an error message.
        */
        if (hasCamera()) {
            /*
                If the activity contains a valid SurfaceView for the preview, then set it up.
                Otherwise, display an error message.
             */
            if (mPreview != null) {
                /*  Initialize fields for executing code on the UI thread. We are using this for
                hiding the preview of a taken picture after a short delay. */
                mHidePictureDelay = getResources().getInteger(R.integer.picture_taken_show_duration);
                mHandler = new Handler(Looper.getMainLooper());
                // Get back-facing camera info.
                mBackCameraId = findCameraId(false);
                // If the device has a front-facing camera, determine what camera we open first.
                if (hasFrontCamera()) {
                    mFrontCameraId = findCameraId(true);
                    mIsFrontCamera = savedInstanceState != null && savedInstanceState.getBoolean(STATE_IS_FRONT_CAMERA, false);
                    mSwitchButton.setOnClickListener(this);
                } else {
                    mFrontCameraId = NO_CAMERA;
                    mSwitchButton.setVisibility(View.GONE);
                }
                hideError();
            } else {
                /*  Disable picture-taking button if there is no camera preview since we cannot take
                pictures with the Camera if there is no preview. */
                mCaptureButton.setEnabled(false);
                showError(R.string.error_preview_surface_view_does_not_exist);
            }
        } else {
            showError(R.string.error_no_camera);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        // If there is a hardware camera then open it and start setting up the preview surface.
        if (mPreview != null && hasCamera()) {
            openCamera();
            mCaptureButton.setOnTouchListener(this);
            mCaptureButton.setOnClickListener(this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Close the camera while we are not using so that other applications can use it.
        closeCamera();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // Save which camera is currently open to state.
        outState.putBoolean(STATE_IS_FRONT_CAMERA, mIsFrontCamera);
    }

    // Camera setup
    /**
     * Check whether the device actually has a camera.
     *
     * @return True if the device has a camera, false otherwise.
     */
    private boolean hasCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    /**
     * Check whether the device has a front-facing camera.
     *
     * @return True if the device has a front-facing camera; false otherwise.
     */
    private boolean hasFrontCamera() {
        final PackageManager packageManager = getPackageManager();
        return packageManager != null && packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT);
    }

    /**
     * Returns the camera ID (an integer between 0 and {@link android.hardware.Camera#getNumberOfCameras()})
     * for either the first front-facing or first back-facing camera.
     *
     * @param front True to find the first front-facing camera; false to find the first back-facing
     *              camera.
     *
     * @return The camera ID for the requested camera as an integer between between 0 and {@link
     * android.hardware.Camera#getNumberOfCameras()} or -1 if there was no matching camera.
     */
    private int findCameraId(boolean front) {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        final int cameraCount = Camera.getNumberOfCameras();
        /*  Iterate through 0…getNumberOfCameras - 1 to find the camera ID of the first front or
        the first back camera. */
        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);
            if ((front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) || (!front && cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK)) {
                return i;
            }
        }
        return NO_CAMERA;
    }

    /**
     * Returns a {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera.
     *
     * @return A {@link android.hardware.Camera.CameraInfo} instance containing information on the
     * currently open camera or `null` if no camera is open.
     */
    private Camera.CameraInfo getCameraInfo() {
        final Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        Camera.getCameraInfo(mIsFrontCamera ? mFrontCameraId : mBackCameraId, cameraInfo);
        return cameraInfo;
    }

    /**
     * Open the first back-facing camera and grab a {@link android.hardware.Camera} instance.
     */
    private void openCamera() {
        if (mCamera != null) {
            if (mPreview.isStarted()) {
                mPreview.stop();
            }
            mCamera.cancelAutoFocus();
            mCamera.release();
        }
        mCamera = Camera.open(mIsFrontCamera ? mFrontCameraId : mBackCameraId);
        final Camera.CameraInfo cameraInfo = getCameraInfo();
        mPreview.setCamera(mCamera, cameraInfo);
        mPreview.start();
        final Camera.Parameters parameters = mCamera.getParameters();
        if (parameters.getMaxNumFocusAreas() > 0) {
            mPreview.startFocusAreaSelection();
            mPreview.setListener(this);
        } else {
            mPreview.stopFocusAreaSelection();
            mPreview.setListener(null);
        }
    }

    /**
     * Close the camera and release the previously obtained {@link android.hardware.Camera} instance
     * to make sure that other applications can grab the camera if needed.
     */
    private void closeCamera() {
        if (mCamera != null) {
            mPreview.setCamera(null, null);
            mCamera.release();
            mCamera = null;
        }
    }

    /**
     * Toggles the camera if we have two cameras available and starts the preview for the new
     * camera.
     */
    private void switchCamera() {
        if (mFrontCameraId != NO_CAMERA) {
            mIsFrontCamera = !mIsFrontCamera;
            openCamera();
        }
    }

    // Auto-focus
    private final Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {

        @Override
        public void onAutoFocus(boolean success, Camera camera) {
        }
    };

    // Picture taking
    /**
     * Callback for retrieving JPEG data when a picture is taken.
     */
    private final Camera.PictureCallback mJpegCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            showPicture(CameraUtils.bitmapFromRawBytes(data, mPictureView.getWidth(), mPictureView.getHeight()));
        }
    };

    /**
     * Checks if the camera is open and takes a picture, retrieving JPEG data.
     */
    private void takePicture() {
        if (mCamera != null) {
            // Take picture and capture raw image data.
            mCamera.takePicture(null, null, mJpegCallback);
        }
    }

    // Show/hide picture taken
    /**
     * Displays a picture taken with the {@link android.hardware.Camera} and hides the preview and
     * capture button.
     *
     * @param bitmap A {@link android.graphics.Bitmap} containing the picture taken.
     */
    private void showPicture(Bitmap bitmap) {
        mPictureView.setImageBitmap(bitmap);
        mPictureView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.INVISIBLE);
        mCaptureButton.setVisibility(View.GONE);
        mHandler.postDelayed(mHidePictureRunnable, mHidePictureDelay);
    }

    /**
     * Hides any shown picture and shows the preview and capture button.
     */
    private void hidePictureTaken() {
        mPreview.start();
        mPictureView.setVisibility(View.INVISIBLE);
        mPreview.setVisibility(View.VISIBLE);
        mCaptureButton.setVisibility(View.VISIBLE);
    }

    // Show/hide error text
    /**
     * Show an error message text and hide the camera preview.
     *
     * @param errorResourceId A resource ID for the error string resource.
     */
    private void showError(int errorResourceId) {
        mErrorTextView.setText(errorResourceId);
        mErrorTextView.setVisibility(View.VISIBLE);
        mPreview.setVisibility(View.GONE);
    }

    /**
     * Hides the error message text and show the camera preview.
     */
    private void hideError() {
        mErrorTextView.setVisibility(View.GONE);
        mPreview.setVisibility(View.VISIBLE);
    }

    // View.OnClickListener implementation
    @Override
    public void onClick(View v) {
        if (v == mSwitchButton) {
            switchCamera();
        } else if (v == mCaptureButton) {
            takePicture();
        }
    }

    // View.OnTouchListener implementation
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (v == mCaptureButton) {

        }
        return false;
    }

    // PreviewListener implementation
    @Override
    public void onAutoFocus() {
        mCamera.autoFocus(mAutoFocusCallback);
    }

    @Override
    public void onFocusAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
            focusAreas.add(new Camera.Area(area, 10));
            parameters.setFocusAreas(focusAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }

    @Override
    public void onMeteringAreaChange(Rect area) {
        if (mCamera != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            final Camera.Parameters parameters = mCamera.getParameters();
            ArrayList<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
            meteringAreas.add(new Camera.Area(area, 10));
            parameters.setMeteringAreas(meteringAreas);
            mCamera.setParameters(parameters);
            mCamera.autoFocus(mAutoFocusCallback);
        }
    }
}