@ -44,6 +44,8 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
public class CameraView extends FrameLayout {
public class CameraView extends FrameLayout {
private final static String TAG = CameraView . class . getSimpleName ( ) ;
private final static String TAG = CameraView . class . getSimpleName ( ) ;
private static final CameraLogger LOG = CameraLogger . create ( TAG ) ;
public final static int PERMISSION_REQUEST_CODE = 16 ;
public final static int PERMISSION_REQUEST_CODE = 16 ;
final static int DEFAULT_JPEG_QUALITY = 100 ;
final static int DEFAULT_JPEG_QUALITY = 100 ;
@ -215,7 +217,7 @@ public class CameraView extends FrameLayout {
protected void onMeasure ( int widthMeasureSpec , int heightMeasureSpec ) {
protected void onMeasure ( int widthMeasureSpec , int heightMeasureSpec ) {
Size previewSize = getPreviewSize ( ) ;
Size previewSize = getPreviewSize ( ) ;
if ( previewSize = = null ) {
if ( previewSize = = null ) {
Log . e ( TAG , "onMeasure, surface is not ready. Calling default behavior." ) ;
LOG . w ( "onMeasure:" , "surface is not ready. Calling default behavior." ) ;
super . onMeasure ( widthMeasureSpec , heightMeasureSpec ) ;
super . onMeasure ( widthMeasureSpec , heightMeasureSpec ) ;
return ;
return ;
}
}
@ -234,18 +236,18 @@ public class CameraView extends FrameLayout {
final ViewGroup . LayoutParams lp = getLayoutParams ( ) ;
final ViewGroup . LayoutParams lp = getLayoutParams ( ) ;
if ( widthMode = = AT_MOST & & lp . width = = MATCH_PARENT ) widthMode = EXACTLY ;
if ( widthMode = = AT_MOST & & lp . width = = MATCH_PARENT ) widthMode = EXACTLY ;
if ( heightMode = = AT_MOST & & lp . height = = MATCH_PARENT ) heightMode = EXACTLY ;
if ( heightMode = = AT_MOST & & lp . height = = MATCH_PARENT ) heightMode = EXACTLY ;
Log . e ( TAG , "onMeasure, requested dimensions are (" +
LOG . i ( "onMeasure:" , "requested dimensions are" ,
widthValue + "[" + ms ( widthMode ) + "]x" +
"(" + widthValue + "[" + ms ( widthMode ) + "]x" +
heightValue + "[" + ms ( heightMode ) + "])" ) ;
heightValue + "[" + ms ( heightMode ) + "])" ) ;
Log . e ( TAG , "onMeasure, previewSize is (" + previewWidth + "x" + previewHeight + ")" ) ;
LOG . i ( "onMeasure:" , "previewSize is" , " (" + previewWidth + "x" + previewHeight + ")" ) ;
// If we have fixed dimensions (either 300dp or MATCH_PARENT), there's nothing we should do,
// If we have fixed dimensions (either 300dp or MATCH_PARENT), there's nothing we should do,
// other than respect it. The preview will eventually be cropped at the sides (by PreviewImpl scaling)
// other than respect it. The preview will eventually be cropped at the sides (by PreviewImpl scaling)
// except the case in which these fixed dimensions manage to fit exactly the preview aspect ratio.
// except the case in which these fixed dimensions manage to fit exactly the preview aspect ratio.
if ( widthMode = = EXACTLY & & heightMode = = EXACTLY ) {
if ( widthMode = = EXACTLY & & heightMode = = EXACTLY ) {
Log . e ( TAG , "onMeasure, both are MATCH_PARENT or fixed value. We adapt. This means CROP_INSIDE. " +
LOG . w ( "onMeasure:" , "both are MATCH_PARENT or fixed value. We adapt." ,
"(" + widthValue + "x" + heightValue + ")" ) ;
"This means CROP_CENTER." , " (" + widthValue + "x" + heightValue + ")" ) ;
super . onMeasure ( widthMeasureSpec , heightMeasureSpec ) ;
super . onMeasure ( widthMeasureSpec , heightMeasureSpec ) ;
return ;
return ;
}
}
@ -253,8 +255,8 @@ public class CameraView extends FrameLayout {
// If both dimensions are free, with no limits, then our size will be exactly the
// If both dimensions are free, with no limits, then our size will be exactly the
// preview size. This can happen rarely, for example in scrollable containers.
// preview size. This can happen rarely, for example in scrollable containers.
if ( widthMode = = UNSPECIFIED & & heightMode = = UNSPECIFIED ) {
if ( widthMode = = UNSPECIFIED & & heightMode = = UNSPECIFIED ) {
Log . e ( TAG , "onMeasure, both are completely free. " +
LOG . i ( "onMeasure:" , "both are completely free." ,
"We respect that and extend to the whole preview size. " +
"We respect that and extend to the whole preview size." ,
"(" + previewWidth + "x" + previewHeight + ")" ) ;
"(" + previewWidth + "x" + previewHeight + ")" ) ;
super . onMeasure (
super . onMeasure (
MeasureSpec . makeMeasureSpec ( ( int ) previewWidth , EXACTLY ) ,
MeasureSpec . makeMeasureSpec ( ( int ) previewWidth , EXACTLY ) ,
@ -279,7 +281,7 @@ public class CameraView extends FrameLayout {
width = widthValue ;
width = widthValue ;
height = ( int ) ( width * ratio ) ;
height = ( int ) ( width * ratio ) ;
}
}
Log . e ( TAG , "onMeasure, on e dimension was free, we adapted it to fit the aspect ratio. " +
LOG . i ( "onMeasure:" , "one dimension was free, we adapted it to fit the aspect ratio." ,
"(" + width + "x" + height + ")" ) ;
"(" + width + "x" + height + ")" ) ;
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
@ -299,8 +301,9 @@ public class CameraView extends FrameLayout {
width = widthValue ;
width = widthValue ;
height = Math . min ( ( int ) ( width * ratio ) , heightValue ) ;
height = Math . min ( ( int ) ( width * ratio ) , heightValue ) ;
}
}
Log . e ( TAG , "onMeasure, one dimension was EXACTLY, another AT_MOST. We have TRIED to fit " +
LOG . i ( "onMeasure:" , "one dimension was EXACTLY, another AT_MOST." ,
"the aspect ratio, but it's not guaranteed. (" + width + "x" + height + ")" ) ;
"We have TRIED to fit the aspect ratio, but it's not guaranteed." ,
"(" + width + "x" + height + ")" ) ;
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
return ;
return ;
@ -318,7 +321,8 @@ public class CameraView extends FrameLayout {
height = heightValue ;
height = heightValue ;
width = ( int ) ( height / ratio ) ;
width = ( int ) ( height / ratio ) ;
}
}
Log . e ( TAG , "onMeasure, both dimension were AT_MOST. We fit the preview aspect ratio. " +
LOG . i ( "onMeasure:" , "both dimension were AT_MOST." ,
"We fit the preview aspect ratio." ,
"(" + width + "x" + height + ")" ) ;
"(" + width + "x" + height + ")" ) ;
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
super . onMeasure ( MeasureSpec . makeMeasureSpec ( width , EXACTLY ) ,
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
MeasureSpec . makeMeasureSpec ( height , EXACTLY ) ) ;
@ -406,13 +410,13 @@ public class CameraView extends FrameLayout {
// Pass to our own GestureLayouts
// Pass to our own GestureLayouts
CameraOptions options = mCameraController . getCameraOptions ( ) ; // Non null
CameraOptions options = mCameraController . getCameraOptions ( ) ; // Non null
if ( mPinchGestureLayout . onTouchEvent ( event ) ) {
if ( mPinchGestureLayout . onTouchEvent ( event ) ) {
// Log.e(TAG, "pinch!");
LOG . i ( "onTouchEvent" , "pinch!" ) ;
onGesture ( mPinchGestureLayout , options ) ;
onGesture ( mPinchGestureLayout , options ) ;
} else if ( mScrollGestureLayout . onTouchEvent ( event ) ) {
} else if ( mScrollGestureLayout . onTouchEvent ( event ) ) {
// Log.e(TAG, "scroll!");
LOG . i ( "onTouchEvent" , "scroll!" ) ;
onGesture ( mScrollGestureLayout , options ) ;
onGesture ( mScrollGestureLayout , options ) ;
} else if ( mTapGestureLayout . onTouchEvent ( event ) ) {
} else if ( mTapGestureLayout . onTouchEvent ( event ) ) {
// Log.e(TAG, "tap!");
LOG . i ( "onTouchEvent" , "tap!" ) ;
onGesture ( mTapGestureLayout , options ) ;
onGesture ( mTapGestureLayout , options ) ;
}
}
return true ;
return true ;
@ -545,10 +549,9 @@ public class CameraView extends FrameLayout {
return ;
return ;
}
}
}
}
String message = "When the session type is set to video, the RECORD_AUDIO permission " +
LOG . e ( "Permission error:" , "When the session type is set to video," ,
"should be added to the application manifest file." ;
"the RECORD_AUDIO permission should be added to the app manifest file." ) ;
Log . w ( TAG , message ) ;
throw new IllegalStateException ( CameraLogger . lastMessage ) ;
throw new IllegalStateException ( message ) ;
} catch ( PackageManager . NameNotFoundException e ) {
} catch ( PackageManager . NameNotFoundException e ) {
// Not possible.
// Not possible.
}
}
@ -1217,6 +1220,7 @@ public class CameraView extends FrameLayout {
// Outer listeners
// Outer listeners
private ArrayList < CameraListener > mListeners = new ArrayList < > ( 2 ) ;
private ArrayList < CameraListener > mListeners = new ArrayList < > ( 2 ) ;
private CameraLogger mLogger = CameraLogger . create ( CameraCallbacks . class . getSimpleName ( ) ) ;
// Orientation TODO: move this logic into OrientationHelper
// Orientation TODO: move this logic into OrientationHelper
private Integer mDisplayOffset ;
private Integer mDisplayOffset ;
@ -1226,6 +1230,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnCameraOpened ( final CameraOptions options ) {
public void dispatchOnCameraOpened ( final CameraOptions options ) {
mLogger . i ( "dispatchOnCameraOpened" , options ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1238,6 +1243,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnCameraClosed ( ) {
public void dispatchOnCameraClosed ( ) {
mLogger . i ( "dispatchOnCameraClosed" ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1250,6 +1256,7 @@ public class CameraView extends FrameLayout {
public void onCameraPreviewSizeChanged ( ) {
public void onCameraPreviewSizeChanged ( ) {
mLogger . i ( "onCameraPreviewSizeChanged" ) ;
// Camera preview size, as returned by getPreviewSize(), has changed.
// Camera preview size, as returned by getPreviewSize(), has changed.
// Request a layout pass for onMeasure() to do its stuff.
// Request a layout pass for onMeasure() to do its stuff.
// Potentially this will change CameraView size, which changes Surface size,
// Potentially this will change CameraView size, which changes Surface size,
@ -1281,6 +1288,7 @@ public class CameraView extends FrameLayout {
* because it was taken with the front camera .
* because it was taken with the front camera .
* /
* /
public void processImage ( final byte [ ] jpeg , final boolean consistentWithView , final boolean flipHorizontally ) {
public void processImage ( final byte [ ] jpeg , final boolean consistentWithView , final boolean flipHorizontally ) {
mLogger . i ( "processImage" ) ;
mWorkerHandler . post ( new Runnable ( ) {
mWorkerHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1291,8 +1299,8 @@ public class CameraView extends FrameLayout {
int w = consistentWithView ? getWidth ( ) : getHeight ( ) ;
int w = consistentWithView ? getWidth ( ) : getHeight ( ) ;
int h = consistentWithView ? getHeight ( ) : getWidth ( ) ;
int h = consistentWithView ? getHeight ( ) : getWidth ( ) ;
AspectRatio targetRatio = AspectRatio . of ( w , h ) ;
AspectRatio targetRatio = AspectRatio . of ( w , h ) ;
// Log.e(TAG, "is Consistent? " + consistentWithView);
mLogger . i ( "processImage" , "is consistent?" , consistentWithView ) ;
// Log.e(TAG, "viewWidth? " + getWidth() + ", viewHeight? " + getHeight());
mLogger . i ( "processImage" , "viewWidth?" , getWidth ( ) , "viewHeight?" , getHeight ( ) ) ;
jpeg2 = CropHelper . cropToJpeg ( jpeg , targetRatio , mJpegQuality ) ;
jpeg2 = CropHelper . cropToJpeg ( jpeg , targetRatio , mJpegQuality ) ;
}
}
dispatchOnPictureTaken ( jpeg2 ) ;
dispatchOnPictureTaken ( jpeg2 ) ;
@ -1302,6 +1310,7 @@ public class CameraView extends FrameLayout {
public void processSnapshot ( final YuvImage yuv , final boolean consistentWithView , boolean flipHorizontally ) {
public void processSnapshot ( final YuvImage yuv , final boolean consistentWithView , boolean flipHorizontally ) {
mLogger . i ( "processSnapshot" ) ;
mWorkerHandler . post ( new Runnable ( ) {
mWorkerHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1310,6 +1319,8 @@ public class CameraView extends FrameLayout {
int w = consistentWithView ? getWidth ( ) : getHeight ( ) ;
int w = consistentWithView ? getWidth ( ) : getHeight ( ) ;
int h = consistentWithView ? getHeight ( ) : getWidth ( ) ;
int h = consistentWithView ? getHeight ( ) : getWidth ( ) ;
AspectRatio targetRatio = AspectRatio . of ( w , h ) ;
AspectRatio targetRatio = AspectRatio . of ( w , h ) ;
mLogger . i ( "processSnapshot" , "is consistent?" , consistentWithView ) ;
mLogger . i ( "processSnapshot" , "viewWidth?" , getWidth ( ) , "viewHeight?" , getHeight ( ) ) ;
jpeg = CropHelper . cropToJpeg ( yuv , targetRatio , mJpegQuality ) ;
jpeg = CropHelper . cropToJpeg ( yuv , targetRatio , mJpegQuality ) ;
} else {
} else {
ByteArrayOutputStream out = new ByteArrayOutputStream ( ) ;
ByteArrayOutputStream out = new ByteArrayOutputStream ( ) ;
@ -1323,6 +1334,7 @@ public class CameraView extends FrameLayout {
private void dispatchOnPictureTaken ( byte [ ] jpeg ) {
private void dispatchOnPictureTaken ( byte [ ] jpeg ) {
mLogger . i ( "dispatchOnPictureTaken" ) ;
final byte [ ] data = jpeg ;
final byte [ ] data = jpeg ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
@ -1336,6 +1348,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnVideoTaken ( final File video ) {
public void dispatchOnVideoTaken ( final File video ) {
mLogger . i ( "dispatchOnVideoTaken" , video ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1348,6 +1361,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnFocusStart ( @Nullable final Gesture gesture , final PointF point ) {
public void dispatchOnFocusStart ( @Nullable final Gesture gesture , final PointF point ) {
mLogger . i ( "dispatchOnFocusStart" , gesture , point ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1365,6 +1379,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnFocusEnd ( @Nullable final Gesture gesture , final boolean success ,
public void dispatchOnFocusEnd ( @Nullable final Gesture gesture , final boolean success ,
final PointF point ) {
final PointF point ) {
mLogger . i ( "dispatchOnFocusEnd" , gesture , success , point ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1386,6 +1401,7 @@ public class CameraView extends FrameLayout {
@Override
@Override
public void onDisplayOffsetChanged ( int displayOffset ) {
public void onDisplayOffsetChanged ( int displayOffset ) {
mLogger . i ( "onDisplayOffsetChanged" , displayOffset ) ;
mCameraController . onDisplayOffset ( displayOffset ) ;
mCameraController . onDisplayOffset ( displayOffset ) ;
mDisplayOffset = displayOffset ;
mDisplayOffset = displayOffset ;
if ( mDeviceOrientation ! = null ) {
if ( mDeviceOrientation ! = null ) {
@ -1396,6 +1412,7 @@ public class CameraView extends FrameLayout {
@Override
@Override
public void onDeviceOrientationChanged ( int deviceOrientation ) {
public void onDeviceOrientationChanged ( int deviceOrientation ) {
mLogger . i ( "onDeviceOrientationChanged" , deviceOrientation ) ;
mCameraController . onDeviceOrientation ( deviceOrientation ) ;
mCameraController . onDeviceOrientation ( deviceOrientation ) ;
mDeviceOrientation = deviceOrientation ;
mDeviceOrientation = deviceOrientation ;
if ( mDisplayOffset ! = null ) {
if ( mDisplayOffset ! = null ) {
@ -1406,6 +1423,7 @@ public class CameraView extends FrameLayout {
private void dispatchOnOrientationChanged ( final int value ) {
private void dispatchOnOrientationChanged ( final int value ) {
mLogger . i ( "dispatchOnOrientationChanged" , value ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1418,6 +1436,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnZoomChanged ( final float newValue , final PointF [ ] fingers ) {
public void dispatchOnZoomChanged ( final float newValue , final PointF [ ] fingers ) {
mLogger . i ( "dispatchOnZoomChanged" , newValue ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1432,6 +1451,7 @@ public class CameraView extends FrameLayout {
public void dispatchOnExposureCorrectionChanged ( final float newValue ,
public void dispatchOnExposureCorrectionChanged ( final float newValue ,
final float [ ] bounds ,
final float [ ] bounds ,
final PointF [ ] fingers ) {
final PointF [ ] fingers ) {
mLogger . i ( "dispatchOnExposureCorrectionChanged" , newValue ) ;
mUiHandler . post ( new Runnable ( ) {
mUiHandler . post ( new Runnable ( ) {
@Override
@Override
public void run ( ) {
public void run ( ) {
@ -1444,16 +1464,19 @@ public class CameraView extends FrameLayout {
private void addListener ( @NonNull CameraListener cameraListener ) {
private void addListener ( @NonNull CameraListener cameraListener ) {
mLogger . i ( "addListener" ) ;
mListeners . add ( cameraListener ) ;
mListeners . add ( cameraListener ) ;
}
}
private void removeListener ( @NonNull CameraListener cameraListener ) {
private void removeListener ( @NonNull CameraListener cameraListener ) {
mLogger . i ( "removeListener" ) ;
mListeners . remove ( cameraListener ) ;
mListeners . remove ( cameraListener ) ;
}
}
private void clearListeners ( ) {
private void clearListeners ( ) {
mLogger . i ( "clearListeners" ) ;
mListeners . clear ( ) ;
mListeners . clear ( ) ;
}
}
}
}