@ -19,6 +19,9 @@ import java.util.ArrayList;
import java.util.Collections ;
import java.util.Collections ;
import java.util.List ;
import java.util.List ;
import static android.hardware.Camera.CAMERA_ERROR_SERVER_DIED ;
import static android.hardware.Camera.CAMERA_ERROR_UNKNOWN ;
@SuppressWarnings ( "deprecation" )
@SuppressWarnings ( "deprecation" )
class Camera1 extends CameraController {
class Camera1 extends CameraController {
@ -37,6 +40,7 @@ class Camera1 extends CameraController {
private Runnable mPostFocusResetRunnable = new Runnable ( ) {
private Runnable mPostFocusResetRunnable = new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
try {
if ( ! isCameraAvailable ( ) ) return ;
if ( ! isCameraAvailable ( ) ) return ;
mCamera . cancelAutoFocus ( ) ;
mCamera . cancelAutoFocus ( ) ;
synchronized ( mLock ) {
synchronized ( mLock ) {
@ -47,6 +51,15 @@ class Camera1 extends CameraController {
mCamera . setParameters ( params ) ;
mCamera . setParameters ( params ) ;
}
}
}
}
catch ( Exception e ) {
// at least setParameters may fail.
// problem may be device-specific to the Samsung Galaxy J5
// TODO why does it fail occasionally and is it possible to prevent such errors?
CameraException cameraException = new CameraConfigurationFailedException ( "Failed to " +
"reset auto focus." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
} ;
} ;
private Mapper mMapper = new Mapper . Mapper1 ( ) ;
private Mapper mMapper = new Mapper . Mapper1 ( ) ;
@ -75,8 +88,9 @@ class Camera1 extends CameraController {
try {
try {
setup ( ) ;
setup ( ) ;
} catch ( Exception e ) {
} catch ( Exception e ) {
LOG . w ( "onSurfaceAvailable:" , "Exception while binding camera to preview." , e ) ;
CameraException cameraException = new CameraUnavailableException (
throw new RuntimeException ( e ) ;
"onSurfaceAvailable: Exception while binding camera to preview." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
}
}
} ) ;
} ) ;
@ -164,6 +178,38 @@ class Camera1 extends CameraController {
if ( collectCameraId ( ) ) {
if ( collectCameraId ( ) ) {
mCamera = Camera . open ( mCameraId ) ;
mCamera = Camera . open ( mCameraId ) ;
/ * *
* attach Android native error listener for the Camera1 API
* TODO it ' s not yet sure how the caught errors interact with the exceptions caught
* outside of the following handler . Furthermore , for most errors it ' s not known whether
* they are crucial or not . Therefore , such errors are handled as low - priority
* CameraConfigurationFailedExceptions for now .
* /
mCamera . setErrorCallback ( new Camera . ErrorCallback ( ) {
@Override
public void onError ( int errorCode , Camera camera ) {
// extend error information by known error codes
CameraException cameraException ;
if ( errorCode = = CAMERA_ERROR_SERVER_DIED ) {
cameraException = new CameraUnavailableException (
"Media server died. In this case, the application must release the" +
" Camera object and instantiate a new one." ) ;
}
else if ( errorCode = = CAMERA_ERROR_UNKNOWN ) {
cameraException = new CameraConfigurationFailedException (
"Unspecified camera error." ) ;
}
else {
cameraException = new CameraConfigurationFailedException (
"Received camera error code: " + errorCode ) ;
}
// redirect error
mCameraCallbacks . onError ( cameraException ) ;
}
} ) ;
// Set parameters that might have been set before the camera was opened.
// Set parameters that might have been set before the camera was opened.
synchronized ( mLock ) {
synchronized ( mLock ) {
LOG . i ( "onStart:" , "Applying default parameters." ) ;
LOG . i ( "onStart:" , "Applying default parameters." ) ;
@ -250,6 +296,7 @@ class Camera1 extends CameraController {
@Override
@Override
void setLocation ( Location location ) {
void setLocation ( Location location ) {
try {
Location oldLocation = mLocation ;
Location oldLocation = mLocation ;
mLocation = location ;
mLocation = location ;
if ( isCameraAvailable ( ) ) {
if ( isCameraAvailable ( ) ) {
@ -259,6 +306,12 @@ class Camera1 extends CameraController {
}
}
}
}
}
}
catch ( Exception e ) {
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set the location." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
private boolean mergeLocation ( Camera . Parameters params , Location oldLocation ) {
private boolean mergeLocation ( Camera . Parameters params , Location oldLocation ) {
if ( mLocation ! = null ) {
if ( mLocation ! = null ) {
@ -288,6 +341,7 @@ class Camera1 extends CameraController {
@Override
@Override
void setWhiteBalance ( WhiteBalance whiteBalance ) {
void setWhiteBalance ( WhiteBalance whiteBalance ) {
try {
WhiteBalance old = mWhiteBalance ;
WhiteBalance old = mWhiteBalance ;
mWhiteBalance = whiteBalance ;
mWhiteBalance = whiteBalance ;
if ( isCameraAvailable ( ) ) {
if ( isCameraAvailable ( ) ) {
@ -297,6 +351,13 @@ class Camera1 extends CameraController {
}
}
}
}
}
}
catch ( Exception e ) {
// TODO handle, !mergeWhiteBalance, too?
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set the white balance." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
private boolean mergeWhiteBalance ( Camera . Parameters params , WhiteBalance oldWhiteBalance ) {
private boolean mergeWhiteBalance ( Camera . Parameters params , WhiteBalance oldWhiteBalance ) {
if ( mOptions . supports ( mWhiteBalance ) ) {
if ( mOptions . supports ( mWhiteBalance ) ) {
@ -309,6 +370,7 @@ class Camera1 extends CameraController {
@Override
@Override
void setHdr ( Hdr hdr ) {
void setHdr ( Hdr hdr ) {
try {
Hdr old = mHdr ;
Hdr old = mHdr ;
mHdr = hdr ;
mHdr = hdr ;
if ( isCameraAvailable ( ) ) {
if ( isCameraAvailable ( ) ) {
@ -318,6 +380,13 @@ class Camera1 extends CameraController {
}
}
}
}
}
}
catch ( Exception e ) {
// TODO handle, !mergeHdr, too?
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set hdr." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
private boolean mergeHdr ( Camera . Parameters params , Hdr oldHdr ) {
private boolean mergeHdr ( Camera . Parameters params , Hdr oldHdr ) {
if ( mOptions . supports ( mHdr ) ) {
if ( mOptions . supports ( mHdr ) ) {
@ -341,6 +410,7 @@ class Camera1 extends CameraController {
@Override
@Override
void setFlash ( Flash flash ) {
void setFlash ( Flash flash ) {
try {
Flash old = mFlash ;
Flash old = mFlash ;
mFlash = flash ;
mFlash = flash ;
if ( isCameraAvailable ( ) ) {
if ( isCameraAvailable ( ) ) {
@ -350,6 +420,13 @@ class Camera1 extends CameraController {
}
}
}
}
}
}
catch ( Exception e ) {
// TODO handle, !mergeFlash, too?
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set flash." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
private boolean mergeFlash ( Camera . Parameters params , Flash oldFlash ) {
private boolean mergeFlash ( Camera . Parameters params , Flash oldFlash ) {
@ -391,6 +468,8 @@ class Camera1 extends CameraController {
@Override
@Override
void setVideoQuality ( VideoQuality videoQuality ) {
void setVideoQuality ( VideoQuality videoQuality ) {
try {
if ( mIsCapturingVideo ) {
if ( mIsCapturingVideo ) {
// TODO: actually any call to getParameters() could fail while recording a video.
// TODO: actually any call to getParameters() could fail while recording a video.
// See. https://stackoverflow.com/questions/14941625/correct-handling-of-exception-getparameters-failed-empty-parameters
// See. https://stackoverflow.com/questions/14941625/correct-handling-of-exception-getparameters-failed-empty-parameters
@ -416,6 +495,12 @@ class Camera1 extends CameraController {
LOG . i ( "setVideoQuality:" , "previewSize:" , mPreviewSize ) ;
LOG . i ( "setVideoQuality:" , "previewSize:" , mPreviewSize ) ;
}
}
}
}
catch ( Exception e ) {
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set video quality." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
}
}
@Override
@Override
boolean capturePicture ( ) {
boolean capturePicture ( ) {
@ -425,6 +510,7 @@ class Camera1 extends CameraController {
if ( ! mOptions . isVideoSnapshotSupported ( ) ) return false ;
if ( ! mOptions . isVideoSnapshotSupported ( ) ) return false ;
}
}
try {
// Set boolean to wait for image callback
// Set boolean to wait for image callback
mIsCapturingImage = true ;
mIsCapturingImage = true ;
final int exifRotation = computeExifRotation ( ) ;
final int exifRotation = computeExifRotation ( ) ;
@ -456,6 +542,12 @@ class Camera1 extends CameraController {
} ) ;
} ) ;
return true ;
return true ;
}
}
catch ( Exception e ) {
CameraException cameraException = new CapturingPictureFailedException ( "Capturing a picture failed." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
@Override
@Override
@ -468,6 +560,8 @@ class Camera1 extends CameraController {
capturePicture ( ) ;
capturePicture ( ) ;
return false ;
return false ;
}
}
try {
mIsCapturingImage = true ;
mIsCapturingImage = true ;
mCamera . setOneShotPreviewCallback ( new Camera . PreviewCallback ( ) {
mCamera . setOneShotPreviewCallback ( new Camera . PreviewCallback ( ) {
@Override
@Override
@ -500,6 +594,12 @@ class Camera1 extends CameraController {
} ) ;
} ) ;
return true ;
return true ;
}
}
catch ( Exception e ) {
CameraException cameraException = new CapturingSnapshotFailedException ( "Capturing a snapshot failed." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
@Override
@Override
boolean shouldFlipSizes ( ) {
boolean shouldFlipSizes ( ) {
@ -619,14 +719,20 @@ class Camera1 extends CameraController {
mMediaRecorder . start ( ) ;
mMediaRecorder . start ( ) ;
return true ;
return true ;
} catch ( Exception e ) {
} catch ( Exception e ) {
LOG . e ( "Error while starting MediaRecorder. Swallowing." , e ) ;
CameraException cameraException =
new CapturingVideoFailedException ( "Error while starting MediaRecorder. " +
"Swallowing." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
mVideoFile = null ;
mVideoFile = null ;
mCamera . lock ( ) ;
mCamera . lock ( ) ;
endVideo ( ) ;
endVideo ( ) ;
return false ;
return false ;
}
}
} else {
} else {
throw new IllegalStateException ( "Can't record video while session type is picture" ) ;
CameraException cameraException =
new CapturingVideoFailedException ( "Can't record video while session type is picture" ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
}
}
@ -736,6 +842,7 @@ class Camera1 extends CameraController {
@Override
@Override
boolean setZoom ( float zoom ) {
boolean setZoom ( float zoom ) {
try {
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! mOptions . isZoomSupported ( ) ) return false ;
if ( ! mOptions . isZoomSupported ( ) ) return false ;
synchronized ( mLock ) {
synchronized ( mLock ) {
@ -746,10 +853,19 @@ class Camera1 extends CameraController {
}
}
return true ;
return true ;
}
}
catch ( Exception e ) {
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set zoom." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
@Override
@Override
boolean setExposureCorrection ( float EVvalue ) {
boolean setExposureCorrection ( float EVvalue ) {
try {
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! mOptions . isExposureCorrectionSupported ( ) ) return false ;
if ( ! mOptions . isExposureCorrectionSupported ( ) ) return false ;
float max = mOptions . getExposureCorrectionMaxValue ( ) ;
float max = mOptions . getExposureCorrectionMaxValue ( ) ;
@ -763,6 +879,14 @@ class Camera1 extends CameraController {
}
}
return true ;
return true ;
}
}
catch ( Exception e ) {
CameraException cameraException =
new CameraConfigurationFailedException ( "Failed to set exposure correction." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
// -----------------
// -----------------
// Tap to focus stuff.
// Tap to focus stuff.
@ -772,6 +896,8 @@ class Camera1 extends CameraController {
boolean startAutoFocus ( @Nullable final Gesture gesture , PointF point ) {
boolean startAutoFocus ( @Nullable final Gesture gesture , PointF point ) {
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! isCameraAvailable ( ) ) return false ;
if ( ! mOptions . isAutoFocusSupported ( ) ) return false ;
if ( ! mOptions . isAutoFocusSupported ( ) ) return false ;
try {
final PointF p = new PointF ( point . x , point . y ) ; // copy.
final PointF p = new PointF ( point . x , point . y ) ; // copy.
List < Camera . Area > meteringAreas2 = computeMeteringAreas ( p . x , p . y ) ;
List < Camera . Area > meteringAreas2 = computeMeteringAreas ( p . x , p . y ) ;
List < Camera . Area > meteringAreas1 = meteringAreas2 . subList ( 0 , 1 ) ;
List < Camera . Area > meteringAreas1 = meteringAreas2 . subList ( 0 , 1 ) ;
@ -798,6 +924,15 @@ class Camera1 extends CameraController {
}
}
return true ;
return true ;
}
}
catch ( Exception e ) {
// at least getParameters and setParameters may fail.
// TODO why do they fail and is it possible to prevent such errors?
CameraException cameraException = new CameraConfigurationFailedException ( "Failed to " +
"start auto focus." , e ) ;
mCameraCallbacks . onError ( cameraException ) ;
return false ;
}
}
private List < Camera . Area > computeMeteringAreas ( double viewClickX , double viewClickY ) {
private List < Camera . Area > computeMeteringAreas ( double viewClickX , double viewClickY ) {