@ -7,7 +7,6 @@ import android.view.Surface;
import org.thoughtcrime.securesms.logging.Log ;
import org.thoughtcrime.securesms.logging.Log ;
import java.io.IOException ;
import java.util.Collections ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.Comparator ;
import java.util.List ;
import java.util.List ;
@ -16,6 +15,9 @@ public class Camera1Controller {
private static final String TAG = Camera1Controller . class . getSimpleName ( ) ;
private static final String TAG = Camera1Controller . class . getSimpleName ( ) ;
private final int screenWidth ;
private final int screenHeight ;
private Camera camera ;
private Camera camera ;
private int cameraId ;
private int cameraId ;
private OrderEnforcer < Stage > enforcer ;
private OrderEnforcer < Stage > enforcer ;
@ -23,10 +25,12 @@ public class Camera1Controller {
private SurfaceTexture previewSurface ;
private SurfaceTexture previewSurface ;
private int screenRotation ;
private int screenRotation ;
public Camera1Controller ( int preferredDirection , @NonNull EventListener eventListener ) {
public Camera1Controller ( int preferredDirection , int screenWidth , int screenHeight , @NonNull EventListener eventListener ) {
this . eventListener = eventListener ;
this . eventListener = eventListener ;
this . enforcer = new OrderEnforcer < > ( Stage . INITIALIZED , Stage . PREVIEW_STARTED ) ;
this . enforcer = new OrderEnforcer < > ( Stage . INITIALIZED , Stage . PREVIEW_STARTED ) ;
this . cameraId = Camera . getNumberOfCameras ( ) > 1 ? preferredDirection : Camera . CameraInfo . CAMERA_FACING_BACK ;
this . cameraId = Camera . getNumberOfCameras ( ) > 1 ? preferredDirection : Camera . CameraInfo . CAMERA_FACING_BACK ;
this . screenWidth = screenWidth ;
this . screenHeight = screenHeight ;
}
}
public void initialize ( ) {
public void initialize ( ) {
@ -49,11 +53,18 @@ public class Camera1Controller {
return ;
return ;
}
}
Camera . Parameters params = camera . getParameters ( ) ;
Camera . Parameters params = camera . getParameters ( ) ;
Camera . Size maxSize = getMaxSupportedPreviewSize ( camera ) ;
Camera . Size previewSize = getClosestSize ( camera . getParameters ( ) . getSupportedPreviewSizes ( ) , screenWidth , screenHeight ) ;
final List < String > focusModes = params . getSupportedFocusModes ( ) ;
Camera . Size pictureSize = getClosestSize ( camera . getParameters ( ) . getSupportedPictureSizes ( ) , screenWidth , screenHeight ) ;
final List < String > focusModes = params . getSupportedFocusModes ( ) ;
Log . d ( TAG , "Preview size: " + previewSize . width + "x" + previewSize . height + " Picture size: " + pictureSize . width + "x" + pictureSize . height ) ;
params . setPreviewSize ( maxSize . width , maxSize . height ) ;
params . setPreviewSize ( previewSize . width , previewSize . height ) ;
params . setPictureSize ( pictureSize . width , pictureSize . height ) ;
params . setFlashMode ( Camera . Parameters . FLASH_MODE_OFF ) ;
params . setColorEffect ( Camera . Parameters . EFFECT_NONE ) ;
params . setWhiteBalance ( Camera . Parameters . WHITE_BALANCE_AUTO ) ;
if ( focusModes . contains ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_PICTURE ) ) {
if ( focusModes . contains ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_PICTURE ) ) {
params . setFocusMode ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_PICTURE ) ;
params . setFocusMode ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_PICTURE ) ;
@ -61,6 +72,7 @@ public class Camera1Controller {
params . setFocusMode ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_VIDEO ) ;
params . setFocusMode ( Camera . Parameters . FOCUS_MODE_CONTINUOUS_VIDEO ) ;
}
}
camera . setParameters ( params ) ;
camera . setParameters ( params ) ;
enforcer . markCompleted ( Stage . INITIALIZED ) ;
enforcer . markCompleted ( Stage . INITIALIZED ) ;
@ -96,6 +108,14 @@ public class Camera1Controller {
} ) ;
} ) ;
}
}
public void capture ( @NonNull CaptureCallback callback ) {
enforcer . run ( Stage . PREVIEW_STARTED , ( ) - > {
camera . takePicture ( null , null , null , ( data , camera ) - > {
callback . onCaptureAvailable ( data , cameraId = = Camera . CameraInfo . CAMERA_FACING_FRONT ) ;
} ) ;
} ) ;
}
public int flip ( ) {
public int flip ( ) {
Log . d ( TAG , "flip()" ) ;
Log . d ( TAG , "flip()" ) ;
SurfaceTexture surfaceTexture = previewSurface ;
SurfaceTexture surfaceTexture = previewSurface ;
@ -115,13 +135,15 @@ public class Camera1Controller {
Log . d ( TAG , "setScreenRotation(" + screenRotation + ") executing" ) ;
Log . d ( TAG , "setScreenRotation(" + screenRotation + ") executing" ) ;
this . screenRotation = screenRotation ;
this . screenRotation = screenRotation ;
int rotation = getCameraRotationForScree n( screenRotation ) ;
int previewRotation = getPreviewRotatio n( screenRotation ) ;
camera . setDisplayOrientation ( r otation) ;
int outputRotation = getOutputRotation ( screenR otation) ;
Log . d ( TAG , "Set camera rotation to: " + rotation ) ;
Log . d ( TAG , "Preview rotation: " + previewRotation + " Output rotation: " + outputRotation ) ;
camera . setDisplayOrientation ( previewRotation ) ;
Camera . Parameters params = camera . getParameters ( ) ;
Camera . Parameters params = camera . getParameters ( ) ;
params . setRotation ( r otation) ;
params . setRotation ( outputR otation) ;
camera . setParameters ( params ) ;
camera . setParameters ( params ) ;
} ) ;
} ) ;
}
}
@ -136,33 +158,58 @@ public class Camera1Controller {
return new Properties ( Camera . getNumberOfCameras ( ) , previewSize . width , previewSize . height ) ;
return new Properties ( Camera . getNumberOfCameras ( ) , previewSize . width , previewSize . height ) ;
}
}
private Camera . Size getMaxSupportedPreviewSize ( Camera camera ) {
private Camera . Size getClosestSize ( List < Camera . Size > sizes , int width , int height ) {
List < Camera . Size > cameraSizes = camera . getParameters ( ) . getSupportedPreviewSizes ( ) ;
Collections . sort ( sizes , ASC_SIZE_COMPARATOR ) ;
Collections . sort ( cameraSizes , DESC_SIZE_COMPARATOR ) ;
return cameraSizes . get ( 0 ) ;
int i = 0 ;
while ( i < sizes . size ( ) & & ( sizes . get ( i ) . width * sizes . get ( i ) . height ) < ( width * height ) ) {
i + + ;
}
return sizes . get ( Math . min ( i , sizes . size ( ) - 1 ) ) ;
}
}
private int getCameraRotationForScreen ( int screenRotation ) {
private int get OutputRotation( int displayRotationCode ) {
int degrees = 0 ;
int degrees = convertRotationToDegrees ( displayRotationCode ) ;
switch ( screenRotation ) {
Camera . CameraInfo info = new Camera . CameraInfo ( ) ;
case Surface . ROTATION_0 : degrees = 0 ; break ;
Camera . getCameraInfo ( cameraId , info ) ;
case Surface . ROTATION_90 : degrees = 90 ; break ;
case Surface . ROTATION_180 : degrees = 180 ; break ;
if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_FRONT ) {
case Surface . ROTATION_270 : degrees = 270 ; break ;
return ( info . orientation + degrees ) % 360 ;
} else {
return ( info . orientation - degrees + 360 ) % 360 ;
}
}
}
private int getPreviewRotation ( int displayRotationCode ) {
int degrees = convertRotationToDegrees ( displayRotationCode ) ;
Camera . CameraInfo info = new Camera . CameraInfo ( ) ;
Camera . CameraInfo info = new Camera . CameraInfo ( ) ;
Camera . getCameraInfo ( cameraId , info ) ;
Camera . getCameraInfo ( cameraId , info ) ;
int result ;
if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_FRONT ) {
if ( info . facing = = Camera . CameraInfo . CAMERA_FACING_FRONT ) {
return ( 360 - ( ( info . orientation + degrees ) % 360 ) ) % 360 ;
result = ( info . orientation + degrees ) % 360 ;
result = ( 360 - result ) % 360 ;
} else {
} else {
return ( info . orientation - degrees + 360 ) % 360 ;
result = ( info . orientation - degrees + 360 ) % 360 ;
}
}
return result ;
}
}
private final Comparator < Camera . Size > DESC_SIZE_COMPARATOR = ( o1 , o2 ) - > Integer . compare ( o2 . width * o2 . height , o1 . width * o1 . height ) ;
private int convertRotationToDegrees ( int screenRotation ) {
switch ( screenRotation ) {
case Surface . ROTATION_0 : return 0 ;
case Surface . ROTATION_90 : return 90 ;
case Surface . ROTATION_180 : return 180 ;
case Surface . ROTATION_270 : return 270 ;
}
return 0 ;
}
private final Comparator < Camera . Size > ASC_SIZE_COMPARATOR = ( o1 , o2 ) - > Integer . compare ( o1 . width * o1 . height , o2 . width * o2 . height ) ;
private enum Stage {
private enum Stage {
INITIALIZED , PREVIEW_STARTED
INITIALIZED , PREVIEW_STARTED
@ -194,7 +241,7 @@ public class Camera1Controller {
@Override
@Override
public String toString ( ) {
public String toString ( ) {
return "cameraCount: " + camera + " previewWidth: " + previewWidth + " previewHeight: " + previewHeight ;
return "cameraCount: " + camera Count + " previewWidth: " + previewWidth + " previewHeight: " + previewHeight ;
}
}
}
}
@ -202,4 +249,8 @@ public class Camera1Controller {
void onPropertiesAvailable ( @NonNull Properties properties ) ;
void onPropertiesAvailable ( @NonNull Properties properties ) ;
void onCameraUnavailable ( ) ;
void onCameraUnavailable ( ) ;
}
}
interface CaptureCallback {
void onCaptureAvailable ( @NonNull byte [ ] jpegData , boolean frontFacing ) ;
}
}
}