package io.fotoapparat.hardware.v2.connection;

import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.os.Build;
import android.support.annotation.RequiresApi;

import io.fotoapparat.hardware.operators.ConnectionOperator;
import io.fotoapparat.hardware.v2.CameraThread;
import io.fotoapparat.hardware.v2.capabilities.Characteristics;
import io.fotoapparat.hardware.v2.selection.CameraSelector;
import io.fotoapparat.parameter.LensPosition;

/**
 * A wrapper around {@link CameraDevice.StateCallback} to open and close a camera.
 */
@SuppressWarnings("MissingPermission")
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class CameraConnection implements ConnectionOperator {

    private final CameraSelector cameraSelector;
    private final OpenCameraTask openCameraTask;
    private final GetCharacteristicsTask getCharacteristicsTask;

    private Characteristics characteristics;
    private CameraDevice camera;
    private Listener listener;

    public CameraConnection(CameraSelector cameraSelector,
                            CameraManager manager,
                            CameraThread cameraThread) {
        this.cameraSelector = cameraSelector;
        openCameraTask = new OpenCameraTask(
                manager,
                cameraThread
        );

        getCharacteristicsTask = new GetCharacteristicsTask(
                manager
        );

    }

    @Override
    public void open(LensPosition lensPosition) {
        String cameraId = cameraSelector.findCameraId(lensPosition);

        characteristics = getCharacteristicsTask.execute(cameraId);
        camera = openCameraTask.execute(cameraId);
    }

    @Override
    public void close() {
        if (camera != null) {
            camera.close();
        }
        if (listener != null) {
            listener.onConnectionClosed();
        }
    }

    /**
     * @return characteristics of currently opened camera.
     * @throws IllegalStateException if camera is not opened yet.
     */
    public Characteristics getCharacteristics() {
        if (characteristics == null) {
            throw new IllegalStateException(
                    "Camera was not opened yet. Characteristics are not available.");
        }

        return characteristics;
    }

    /**
     * Returns the open {@link CameraDevice}.
     *
     * @return The requested {@link CameraDevice} to open
     */
    public CameraDevice getCamera() {
        if (camera == null) {
            throw new IllegalStateException(
                    "Camera was not opened yet. Camera is not available.");
        }

        return camera;
    }

    /**
     * Sets the listener to be notified when the connection closes.
     *
     * @param listener The listener to receive the events.
     */
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    /**
     * Notifies the connectivity of the camera.
     */
    public interface Listener {

        /**
         * Called when the connection to the camera has been closed.
         */
        void onConnectionClosed();
    }
}

@@ -800,37 +800,29 @@
 nal 
-Open
 Camera
-Task openCameraTask
+Manager manager
 ;%0A  
@@ -841,53 +841,33 @@
 nal 
-GetCharacteristicsTask getCharacteristicsTask
+CameraThread cameraThread
 ;%0A%0A 
@@ -1200,68 +1200,30 @@
     
-openCameraTask = new OpenCameraTask(%0A               
+this.manager =
  manager
 ,%0A  
@@ -1210,33 +1210,33 @@
 anager = manager
-,
+;
 %0A               
@@ -1224,32 +1224,29 @@
 er;%0A        
-        
+this.
 cameraThread
@@ -1249,117 +1249,24 @@
 read
-%0A        );%0A%0A        getCharacteristicsTask = new GetCharacteristicsTask(%0A                manager%0A        );%0A
+ = cameraThread;
 %0A   
@@ -1429,17 +1429,21 @@
 stics = 
-g
+new G
 etCharac
@@ -1451,24 +1451,59 @@
 eristicsTask
+(%0A                manager%0A        )
 .execute(cam
@@ -1506,24 +1506,25 @@
 (cameraId);%0A
+%0A
         came
@@ -1528,17 +1528,21 @@
 amera = 
-o
+new O
 penCamer
@@ -1546,16 +1546,81 @@
 meraTask
+(%0A                manager,%0A                cameraThread%0A        )
 .execute

Fix lifecycle issue