content: /*
  * Copyright 2015 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *     http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
  
  package com.example.android.basicpermissions.camera;
  
  import android.content.Context;
  import android.hardware.Camera;
  import android.util.AttributeSet;
  import android.util.Log;
  import android.view.Surface;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  
  import java.io.IOException;
  
  /**
   * Camera preview that displays a {@link Camera}.
   * <p>
   * Handles basic lifecycle methods to display and stop the preview.
   * <p>
   * Implementation is based directly on the documentation at
   * http://developer.android.com/guide/topics/media/camera.html
   */
  public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
  
      private static final String TAG = "CameraPreview";
  
      private SurfaceHolder mHolder;
      private Camera mCamera;
      private Camera.CameraInfo mCameraInfo;
      private int mDisplayOrientation;
  
      public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr) {
          this(context, attrs, defStyleAttr, null, null, 0);
      }
  
      public CameraPreview(Context context, AttributeSet attrs, int defStyleAttr,
              Camera camera, Camera.CameraInfo cameraInfo, int displayOrientation) {
          super(context, attrs, defStyleAttr);
  
          // Do not initialise if no camera has been set
          if (camera == null || cameraInfo == null) {
              return;
          }
          mCamera = camera;
          mCameraInfo = cameraInfo;
          mDisplayOrientation = displayOrientation;
  
          // Install a SurfaceHolder.Callback so we get notified when the
          // underlying surface is created and destroyed.
          mHolder = getHolder();
          mHolder.addCallback(this);
      }
  
      /**
       * Calculate the correct orientation for a {@link Camera} preview that is displayed on screen.
       * <p>
       * Implementation is based on the sample code provided in
       * {@link Camera#setDisplayOrientation(int)}.
       */
      public static int calculatePreviewOrientation(Camera.CameraInfo info, int rotation) {
          int degrees = 0;
  
          switch (rotation) {
              case Surface.ROTATION_0:
                  degrees = 0;
                  break;
              case Surface.ROTATION_90:
                  degrees = 90;
                  break;
              case Surface.ROTATION_180:
                  degrees = 180;
                  break;
              case Surface.ROTATION_270:
                  degrees = 270;
                  break;
          }
  
          int result;
          if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
              result = (info.orientation + degrees) % 360;
              result = (360 - result) % 360;  // compensate the mirror
          } else {  // back-facing
              result = (info.orientation - degrees + 360) % 360;
          }
  
          return result;
      }
  
      public void surfaceCreated(SurfaceHolder holder) {
          // The Surface has been created, now tell the camera where to draw the preview.
          try {
              mCamera.setPreviewDisplay(holder);
              mCamera.startPreview();
              Log.d(TAG, "Camera preview started.");
          } catch (IOException e) {
              Log.d(TAG, "Error setting camera preview: " + e.getMessage());
          }
      }
  
      public void surfaceDestroyed(SurfaceHolder holder) {
          // empty. Take care of releasing the Camera preview in your activity.
      }
  
      public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
          // If your preview can change or rotate, take care of those events here.
          // Make sure to stop the preview before resizing or reformatting it.
  
          if (mHolder.getSurface() == null) {
              // preview surface does not exist
              Log.d(TAG, "Preview surface does not exist");
              return;
          }
  
          // stop preview before making changes
          try {
              mCamera.stopPreview();
              Log.d(TAG, "Preview stopped.");
          } catch (Exception e) {
              // ignore: tried to stop a non-existent preview
              Log.d(TAG, "Error starting camera preview: " + e.getMessage());
          }
  
          int orientation = calculatePreviewOrientation(mCameraInfo, mDisplayOrientation);
          mCamera.setDisplayOrientation(orientation);
  
          try {
              mCamera.setPreviewDisplay(mHolder);
              mCamera.startPreview();
              Log.d(TAG, "Camera preview started.");
          } catch (Exception e) {
              Log.d(TAG, "Error starting camera preview: " + e.getMessage());
          }
      }
  }
  