Add nullable and nonnull annotations everywhere

v2
Mattia Iavarone 6 years ago
parent 147f1676ca
commit bc5c9a41b4
  1. 7
      MIGRATION.md
  2. 6
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java
  3. 22
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java
  4. 2
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraPreview.java
  5. 9
      cameraview/src/main/gles/com/otaliastudios/cameraview/AudioMediaEncoder.java
  6. 11
      cameraview/src/main/gles/com/otaliastudios/cameraview/MediaEncoder.java
  7. 4
      cameraview/src/main/gles/com/otaliastudios/cameraview/MediaEncoderEngine.java
  8. 7
      cameraview/src/main/gles/com/otaliastudios/cameraview/TextureMediaEncoder.java
  9. 7
      cameraview/src/main/gles/com/otaliastudios/cameraview/VideoMediaEncoder.java
  10. 9
      cameraview/src/main/java/com/otaliastudios/cameraview/AspectRatio.java
  11. 50
      cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java
  12. 46
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java
  13. 19
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraListener.java
  14. 22
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraOptions.java
  15. 21
      cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java
  16. 7
      cameraview/src/main/java/com/otaliastudios/cameraview/Frame.java
  17. 13
      cameraview/src/main/java/com/otaliastudios/cameraview/FrameManager.java
  18. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/FullPictureRecorder.java
  19. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/FullVideoRecorder.java
  20. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/PictureRecorder.java
  21. 6
      cameraview/src/main/java/com/otaliastudios/cameraview/PictureResult.java
  22. 8
      cameraview/src/main/java/com/otaliastudios/cameraview/SnapshotPictureRecorder.java
  23. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/SnapshotVideoRecorder.java
  24. 3
      cameraview/src/main/java/com/otaliastudios/cameraview/VideoRecorder.java
  25. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/VideoResult.java
  26. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Audio.java
  27. 5
      cameraview/src/main/options/com/otaliastudios/cameraview/Facing.java
  28. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Flash.java
  29. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/GestureAction.java
  30. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Grid.java
  31. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Hdr.java
  32. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Mode.java
  33. 3
      cameraview/src/main/options/com/otaliastudios/cameraview/Preview.java
  34. 4
      cameraview/src/main/options/com/otaliastudios/cameraview/VideoCodec.java
  35. 2
      cameraview/src/main/options/com/otaliastudios/cameraview/WhiteBalance.java
  36. 38
      cameraview/src/main/utils/com/otaliastudios/cameraview/CameraLogger.java
  37. 21
      cameraview/src/main/utils/com/otaliastudios/cameraview/CameraUtils.java
  38. 4
      cameraview/src/main/utils/com/otaliastudios/cameraview/CropHelper.java
  39. 5
      cameraview/src/main/utils/com/otaliastudios/cameraview/OrientationHelper.java
  40. 11
      cameraview/src/main/utils/com/otaliastudios/cameraview/RotationHelper.java
  41. 35
      cameraview/src/main/utils/com/otaliastudios/cameraview/SizeSelectors.java
  42. 13
      cameraview/src/main/utils/com/otaliastudios/cameraview/WorkerHandler.java
  43. 14
      cameraview/src/main/views/com/otaliastudios/cameraview/CameraPreview.java
  44. 9
      cameraview/src/main/views/com/otaliastudios/cameraview/GestureLayout.java
  45. 6
      cameraview/src/main/views/com/otaliastudios/cameraview/GlCameraPreview.java
  46. 6
      cameraview/src/main/views/com/otaliastudios/cameraview/GridLinesLayout.java
  47. 9
      cameraview/src/main/views/com/otaliastudios/cameraview/PinchGestureLayout.java
  48. 10
      cameraview/src/main/views/com/otaliastudios/cameraview/ScrollGestureLayout.java
  49. 7
      cameraview/src/main/views/com/otaliastudios/cameraview/SurfaceCameraPreview.java
  50. 19
      cameraview/src/main/views/com/otaliastudios/cameraview/TapGestureLayout.java
  51. 7
      cameraview/src/main/views/com/otaliastudios/cameraview/TextureCameraPreview.java
  52. 4
      cameraview/src/test/java/com/otaliastudios/cameraview/SizeSelectorsTest.java
  53. 6
      demo/src/main/java/com/otaliastudios/cameraview/demo/CameraActivity.java

@ -124,13 +124,16 @@ The listener interface brings two breaking signature changes:
- `onVideoTaken()` now returns a `VideoResult`. Use `result.getFile()` to access the video file.
The result class includes rich information about the video (or video snapshot) that was taken.
## Experimental mode
The v2 version introduces a `cameraExperimental` XML flag that you can use to enable experimental features.
Might be used in the future to speed up development.
## Other improvements
- Added `@Nullable` and `@NonNull` annotations pretty much everywhere. This might **break** your Kotlin build.
- Added `setGridColor()` and `cameraGridColor` to control the grid color
- Default `Facing` value is not `BACK` anymore but rather a value that guarantees that you have cameras (if possible).
If device has no `BACK` cameras, defaults to `FRONT`.
TODO: max size for video snapshot is naive
TODO: document cameraGridColor
TODO: document setVideoBitRate
TODO: document setAudioBitRate

@ -642,9 +642,9 @@ public class CameraViewTest extends BaseTest {
assertTrue(cameraView.mFrameProcessors.isEmpty());
// Ensure this does not throw a ConcurrentModificationException
cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} });
cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} });
cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} });
cameraView.addFrameProcessor(new FrameProcessor() { public void process(@NonNull Frame f) {} });
cameraView.addFrameProcessor(new FrameProcessor() { public void process(@NonNull Frame f) {} });
cameraView.addFrameProcessor(new FrameProcessor() { public void process(@NonNull Frame f) {} });
for (FrameProcessor test : cameraView.mFrameProcessors) {
cameraView.mFrameProcessors.remove(test);
}

@ -40,49 +40,49 @@ public class MockCameraController extends CameraController {
}
@Override
void setZoom(float zoom, PointF[] points, boolean notify) {
void setZoom(float zoom, @Nullable PointF[] points, boolean notify) {
mZoomValue = zoom;
mZoomChanged = true;
}
@Override
void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify) {
void setExposureCorrection(float EVvalue, @NonNull float[] bounds, @Nullable PointF[] points, boolean notify) {
mExposureCorrectionValue = EVvalue;
mExposureCorrectionChanged = true;
}
@Override
void setFacing(Facing facing) {
void setFacing(@NonNull Facing facing) {
mFacing = facing;
}
@Override
void setFlash(Flash flash) {
void setFlash(@NonNull Flash flash) {
mFlash = flash;
}
@Override
void setWhiteBalance(WhiteBalance whiteBalance) {
void setWhiteBalance(@NonNull WhiteBalance whiteBalance) {
mWhiteBalance = whiteBalance;
}
@Override
void setMode(Mode mode) {
void setMode(@NonNull Mode mode) {
mMode = mode;
}
@Override
void setHdr(Hdr hdr) {
void setHdr(@NonNull Hdr hdr) {
mHdr = hdr;
}
@Override
void setAudio(Audio audio) {
void setAudio(@NonNull Audio audio) {
mAudio = audio;
}
@Override
void setLocation(Location location) {
void setLocation(@Nullable Location location) {
mLocation = location;
}
@ -92,7 +92,7 @@ public class MockCameraController extends CameraController {
}
@Override
void takePictureSnapshot(AspectRatio viewAspectRatio) {
void takePictureSnapshot(@NonNull AspectRatio viewAspectRatio) {
}
@Override
@ -127,7 +127,7 @@ public class MockCameraController extends CameraController {
}
@Override
public void onBufferAvailable(byte[] buffer) {
public void onBufferAvailable(@NonNull byte[] buffer) {
}
@Override

@ -30,11 +30,13 @@ public class MockCameraPreview extends CameraPreview<View, Void> {
return new View(context);
}
@NonNull
@Override
Class<Void> getOutputClass() {
return null;
}
@NonNull
@Override
Void getOutput() {
return null;

@ -9,6 +9,7 @@ import android.media.MediaMuxer;
import android.media.MediaRecorder;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import java.io.IOException;
@ -40,7 +41,7 @@ class AudioMediaEncoder extends MediaEncoder {
@EncoderThread
@Override
void prepare(MediaEncoderEngine.Controller controller, long maxLengthMillis) {
void prepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) {
super.prepare(controller, maxLengthMillis);
final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLE_RATE, 1);
audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
@ -65,7 +66,7 @@ class AudioMediaEncoder extends MediaEncoder {
@EncoderThread
@Override
void notify(String event, Object data) { }
void notify(@NonNull String event, @Nullable Object data) { }
@EncoderThread
@Override
@ -74,7 +75,9 @@ class AudioMediaEncoder extends MediaEncoder {
synchronized (mLock) {
try {
mLock.wait();
} catch (InterruptedException e) {}
} catch (InterruptedException e) {
// do nothing
}
}
}

@ -3,6 +3,8 @@ package com.otaliastudios.cameraview;
import android.media.MediaCodec;
import android.media.MediaFormat;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.Log;
@ -14,6 +16,7 @@ abstract class MediaEncoder {
private final static int TIMEOUT_USEC = 10000; // 10 msec
@SuppressWarnings("WeakerAccess")
protected MediaCodec mMediaCodec;
private MediaCodec.BufferInfo mBufferInfo;
@ -32,7 +35,7 @@ abstract class MediaEncoder {
* @param controller the muxer controller
*/
@EncoderThread
void prepare(MediaEncoderEngine.Controller controller, long maxLengthMillis) {
void prepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) {
mController = controller;
mBufferInfo = new MediaCodec.BufferInfo();
mMaxLengthMillis = maxLengthMillis;
@ -53,7 +56,7 @@ abstract class MediaEncoder {
* @param data object
*/
@EncoderThread
abstract void notify(String event, Object data);
abstract void notify(@NonNull String event, @Nullable Object data);
/**
* Stop recording.
@ -77,7 +80,8 @@ abstract class MediaEncoder {
/**
* Encode data into the {@link #mMediaCodec}.
*/
protected void encode(final ByteBuffer buffer, final int length, final long presentationTimeUs) {
@SuppressWarnings("WeakerAccess")
protected void encode(@Nullable final ByteBuffer buffer, final int length, final long presentationTimeUs) {
final ByteBuffer[] inputBuffers = mMediaCodec.getInputBuffers();
while (true) {
final int inputBufferIndex = mMediaCodec.dequeueInputBuffer(TIMEOUT_USEC);
@ -111,6 +115,7 @@ abstract class MediaEncoder {
* is set, we send EOS to the encoder, and then iterate until we see EOS on the output.
* Calling this with endOfStream set should be done once, right before stopping the muxer.
*/
@SuppressWarnings("WeakerAccess")
protected void drain(boolean endOfStream) {
if (endOfStream) {
mMediaCodec.signalEndOfInputStream();

@ -19,6 +19,7 @@ import java.util.List;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
class MediaEncoderEngine {
@SuppressWarnings("WeakerAccess")
final static int STOP_BY_USER = 0;
final static int STOP_BY_MAX_DURATION = 1;
final static int STOP_BY_MAX_SIZE = 2;
@ -56,13 +57,14 @@ class MediaEncoderEngine {
public void run() {
// Trying to convert the size constraints to duration constraints,
// because they are super easy to check.
// This is really naive & not accurate, but...
// This is really naive & probably not accurate, but...
int bitRate = 0;
for (MediaEncoder encoder : mEncoders) {
bitRate += encoder.getBitRate();
}
int bytePerSecond = bitRate / 8;
long sizeMaxDuration = (maxSize / bytePerSecond) * 1000L;
long finalMaxDuration = Long.MAX_VALUE;
if (maxSize > 0 && maxDuration > 0) {
mPossibleStopReason = sizeMaxDuration < maxDuration ? STOP_BY_MAX_SIZE : STOP_BY_MAX_DURATION;

@ -9,6 +9,7 @@ import android.opengl.EGLContext;
import android.opengl.Matrix;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.util.Log;
import android.view.Surface;
@ -46,13 +47,13 @@ class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.Config>
private EglWindowSurface mWindow;
private EglViewport mViewport;
public TextureMediaEncoder(@NonNull Config config) {
TextureMediaEncoder(@NonNull Config config) {
super(config);
}
@EncoderThread
@Override
void prepare(MediaEncoderEngine.Controller controller, long maxLengthMillis) {
void prepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) {
super.prepare(controller, maxLengthMillis);
mEglCore = new EglCore(mConfig.eglContext, EglCore.FLAG_RECORDABLE);
mWindow = new EglWindowSurface(mEglCore, mSurface, true);
@ -90,7 +91,7 @@ class TextureMediaEncoder extends VideoMediaEncoder<TextureMediaEncoder.Config>
@EncoderThread
@Override
void notify(String event, Object data) {
void notify(@NonNull String event, @Nullable Object data) {
if (event.equals(FRAME_EVENT)) {
Frame frame = (Frame) data;

@ -22,8 +22,13 @@ import java.nio.ByteBuffer;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
abstract class VideoMediaEncoder<C extends VideoMediaEncoder.Config> extends MediaEncoder {
@SuppressWarnings("WeakerAccess")
protected C mConfig;
@SuppressWarnings("WeakerAccess")
protected Surface mSurface;
@SuppressWarnings("WeakerAccess")
protected int mFrameNum = -1;
static class Config {
@ -50,7 +55,7 @@ abstract class VideoMediaEncoder<C extends VideoMediaEncoder.Config> extends Med
@EncoderThread
@Override
void prepare(MediaEncoderEngine.Controller controller, long maxLengthMillis) {
void prepare(@NonNull MediaEncoderEngine.Controller controller, long maxLengthMillis) {
super.prepare(controller, maxLengthMillis);
MediaFormat format = MediaFormat.createVideoFormat(mConfig.mimeType, mConfig.width, mConfig.height);

@ -20,6 +20,7 @@ public class AspectRatio implements Comparable<AspectRatio> {
* @param size the size
* @return a (possibly cached) aspect ratio
*/
@NonNull
public static AspectRatio of(Size size) {
return AspectRatio.of(size.getWidth(), size.getHeight());
}
@ -30,6 +31,7 @@ public class AspectRatio implements Comparable<AspectRatio> {
* @param y the height
* @return a (possibly cached) aspect ratio
*/
@NonNull
public static AspectRatio of(int x, int y) {
int gcd = gcd(x, y);
x /= gcd;
@ -50,6 +52,8 @@ public class AspectRatio implements Comparable<AspectRatio> {
* @param string a string of the format x:y where x and y are integers
* @return a (possibly cached) aspect ratio
*/
@NonNull
@SuppressWarnings("WeakerAccess")
public static AspectRatio parse(@NonNull String string) {
String[] parts = string.split(":");
if (parts.length != 2) {
@ -76,7 +80,8 @@ public class AspectRatio implements Comparable<AspectRatio> {
return mY;
}
public boolean matches(Size size) {
@SuppressWarnings("WeakerAccess")
public boolean matches(@NonNull Size size) {
int gcd = gcd(size.getWidth(), size.getHeight());
int x = size.getWidth() / gcd;
int y = size.getHeight() / gcd;
@ -103,6 +108,7 @@ public class AspectRatio implements Comparable<AspectRatio> {
return mX + ":" + mY;
}
@SuppressWarnings("WeakerAccess")
public float toFloat() {
return (float) mX / mY;
}
@ -123,6 +129,7 @@ public class AspectRatio implements Comparable<AspectRatio> {
}
@SuppressWarnings("SuspiciousNameCombination")
@NonNull
public AspectRatio inverse() {
return AspectRatio.of(mY, mX);
}

@ -47,7 +47,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
};
Camera1(CameraView.CameraCallbacks callback) {
Camera1(@NonNull CameraView.CameraCallbacks callback) {
super(callback);
mMapper = new Mapper1();
}
@ -298,7 +298,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
public void onBufferAvailable(byte[] buffer) {
public void onBufferAvailable(@NonNull byte[] buffer) {
// TODO: sync with handler?
if (isCameraAvailable()) {
mCamera.addCallbackBuffer(buffer);
@ -327,7 +327,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setMode(Mode mode) {
void setMode(@NonNull Mode mode) {
if (mode != mMode) {
mMode = mode;
schedule(null, true, new Runnable() {
@ -340,7 +340,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setLocation(Location location) {
void setLocation(@Nullable Location location) {
final Location oldLocation = mLocation;
mLocation = location;
schedule(mLocationTask, true, new Runnable() {
@ -352,7 +352,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
});
}
private boolean applyLocation(Camera.Parameters params, Location oldLocation) {
private boolean applyLocation(@NonNull Camera.Parameters params, @Nullable Location oldLocation) {
if (mLocation != null) {
params.setGpsLatitude(mLocation.getLatitude());
params.setGpsLongitude(mLocation.getLongitude());
@ -364,7 +364,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setFacing(Facing facing) {
void setFacing(@NonNull Facing facing) {
final Facing old = mFacing;
if (facing != old) {
mFacing = facing;
@ -382,7 +382,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setWhiteBalance(WhiteBalance whiteBalance) {
void setWhiteBalance(@NonNull WhiteBalance whiteBalance) {
final WhiteBalance old = mWhiteBalance;
mWhiteBalance = whiteBalance;
schedule(mWhiteBalanceTask, true, new Runnable() {
@ -394,7 +394,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
});
}
private boolean applyWhiteBalance(Camera.Parameters params, WhiteBalance oldWhiteBalance) {
private boolean applyWhiteBalance(@NonNull Camera.Parameters params, @NonNull WhiteBalance oldWhiteBalance) {
if (mCameraOptions.supports(mWhiteBalance)) {
params.setWhiteBalance((String) mMapper.map(mWhiteBalance));
return true;
@ -404,7 +404,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setHdr(Hdr hdr) {
void setHdr(@NonNull Hdr hdr) {
final Hdr old = mHdr;
mHdr = hdr;
schedule(mHdrTask, true, new Runnable() {
@ -416,7 +416,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
});
}
private boolean applyHdr(Camera.Parameters params, Hdr oldHdr) {
private boolean applyHdr(@NonNull Camera.Parameters params, @NonNull Hdr oldHdr) {
if (mCameraOptions.supports(mHdr)) {
params.setSceneMode((String) mMapper.map(mHdr));
return true;
@ -444,7 +444,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
@Override
void setAudio(Audio audio) {
void setAudio(@NonNull Audio audio) {
if (mAudio != audio) {
if (isTakingVideo()) {
LOG.w("Audio setting was changed while recording. " +
@ -455,7 +455,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setFlash(Flash flash) {
void setFlash(@NonNull Flash flash) {
final Flash old = mFlash;
mFlash = flash;
schedule(mFlashTask, true, new Runnable() {
@ -468,7 +468,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
private boolean applyFlash(Camera.Parameters params, Flash oldFlash) {
private boolean applyFlash(@NonNull Camera.Parameters params, @NonNull Flash oldFlash) {
if (mCameraOptions.supports(mFlash)) {
params.setFlashMode((String) mMapper.map(mFlash));
return true;
@ -479,7 +479,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
// Choose the best default focus, based on session type.
private void applyDefaultFocus(Camera.Parameters params) {
private void applyDefaultFocus(@NonNull Camera.Parameters params) {
List<String> modes = params.getSupportedFocusModes();
if (mMode == Mode.VIDEO &&
@ -500,6 +500,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
if (modes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_FIXED);
//noinspection UnnecessaryReturnStatement
return;
}
}
@ -552,7 +553,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
@Override
void takePictureSnapshot(final AspectRatio viewAspectRatio) {
void takePictureSnapshot(@NonNull final AspectRatio viewAspectRatio) {
LOG.v("takePictureSnapshot: scheduling");
schedule(null, true, new Runnable() {
@Override
@ -573,7 +574,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
public void onPreviewFrame(@NonNull byte[] data, Camera camera) {
Frame frame = mFrameManager.getFrame(data,
System.currentTimeMillis(),
offset(REF_SENSOR, REF_OUTPUT),
@ -782,7 +783,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
@Override
void setZoom(final float zoom, final PointF[] points, final boolean notify) {
void setZoom(final float zoom, @Nullable final PointF[] points, final boolean notify) {
schedule(mZoomTask, true, new Runnable() {
@Override
public void run() {
@ -802,8 +803,8 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
@Override
void setExposureCorrection(final float EVvalue, final float[] bounds,
final PointF[] points, final boolean notify) {
void setExposureCorrection(final float EVvalue, @NonNull final float[] bounds,
@Nullable final PointF[] points, final boolean notify) {
schedule(mExposureCorrectionTask, true, new Runnable() {
@Override
public void run() {
@ -831,7 +832,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
@Override
void startAutoFocus(@Nullable final Gesture gesture, final PointF point) {
void startAutoFocus(@Nullable final Gesture gesture, @NonNull final PointF point) {
// Must get width and height from the UI thread.
int viewWidth = 0, viewHeight = 0;
if (mPreview != null && mPreview.hasSurface()) {
@ -880,7 +881,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
});
}
@NonNull
@WorkerThread
private static List<Camera.Area> computeMeteringAreas(double viewClickX, double viewClickY,
int viewWidth, int viewHeight,
@ -911,7 +912,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
return list;
}
@NonNull
private static Rect computeMeteringArea(double centerX, double centerY, double size) {
double delta = size / 2d;
int top = (int) Math.max(centerY - delta, -1000);
@ -928,7 +929,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
@Nullable
private List<Size> sizesFromList(List<Camera.Size> sizes) {
private List<Size> sizesFromList(@Nullable List<Camera.Size> sizes) {
if (sizes == null) return null;
List<Size> result = new ArrayList<>(sizes.size());
for (Camera.Size size : sizes) {
@ -950,8 +951,5 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera
}
});
}
// -----------------
// Additional helper info
}

@ -156,6 +156,7 @@ abstract class CameraController implements
//region Start&Stop
@NonNull
private String ss() {
switch (mState) {
case STATE_STOPPING: return "STATE_STOPPING";
@ -273,11 +274,11 @@ abstract class CameraController implements
mDeviceOrientation = deviceOrientation;
}
final void setPictureSizeSelector(SizeSelector selector) {
final void setPictureSizeSelector(@NonNull SizeSelector selector) {
mPictureSizeSelector = selector;
}
final void setVideoSizeSelector(SizeSelector selector) {
final void setVideoSizeSelector(@NonNull SizeSelector selector) {
mVideoSizeSelector = selector;
}
@ -289,7 +290,7 @@ abstract class CameraController implements
mVideoMaxDuration = videoMaxDurationMillis;
}
final void setVideoCodec(VideoCodec codec) {
final void setVideoCodec(@NonNull VideoCodec codec) {
mVideoCodec = codec;
}
@ -306,35 +307,35 @@ abstract class CameraController implements
//region Abstract setters and APIs
// Should restart the session if active.
abstract void setMode(Mode mode);
abstract void setMode(@NonNull Mode mode);
// Should restart the session if active.
abstract void setFacing(Facing facing);
abstract void setFacing(@NonNull Facing facing);
// If closed, no-op. If opened, check supported and apply.
abstract void setZoom(float zoom, PointF[] points, boolean notify);
abstract void setZoom(float zoom, @Nullable PointF[] points, boolean notify);
// If closed, no-op. If opened, check supported and apply.
abstract void setExposureCorrection(float EVvalue, float[] bounds, PointF[] points, boolean notify);
abstract void setExposureCorrection(float EVvalue, @NonNull float[] bounds, @Nullable PointF[] points, boolean notify);
// If closed, keep. If opened, check supported and apply.
abstract void setFlash(Flash flash);
abstract void setFlash(@NonNull Flash flash);
// If closed, keep. If opened, check supported and apply.
abstract void setWhiteBalance(WhiteBalance whiteBalance);
abstract void setWhiteBalance(@NonNull WhiteBalance whiteBalance);
// If closed, keep. If opened, check supported and apply.
abstract void setHdr(Hdr hdr);
abstract void setHdr(@NonNull Hdr hdr);
// If closed, keep. If opened, check supported and apply.
abstract void setLocation(Location location);
abstract void setLocation(@Nullable Location location);
// Just set.
abstract void setAudio(Audio audio);
abstract void setAudio(@NonNull Audio audio);
abstract void takePicture();
abstract void takePictureSnapshot(AspectRatio viewAspectRatio);
abstract void takePictureSnapshot(@NonNull AspectRatio viewAspectRatio);
abstract void takeVideo(@NonNull File file);
@ -355,14 +356,17 @@ abstract class CameraController implements
return mCameraOptions;
}
@NonNull
final Facing getFacing() {
return mFacing;
}
@NonNull
final Flash getFlash() {
return mFlash;
}
@NonNull
final WhiteBalance getWhiteBalance() {
return mWhiteBalance;
}
@ -383,18 +387,22 @@ abstract class CameraController implements
return mVideoMaxDuration;
}
@NonNull
final Mode getMode() {
return mMode;
}
@NonNull
final Hdr getHdr() {
return mHdr;
}
@Nullable
final Location getLocation() {
return mLocation;
}
@NonNull
final Audio getAudio() {
return mAudio;
}
@ -403,10 +411,12 @@ abstract class CameraController implements
return mAudioBitRate;
}
@NonNull
/* for tests */ final SizeSelector getPictureSizeSelector() {
return mPictureSizeSelector;
}
@NonNull
/* for tests */ final SizeSelector getVideoSizeSelector() {
return mVideoSizeSelector;
}
@ -469,12 +479,12 @@ abstract class CameraController implements
return offset(reference1, reference2) % 180 != 0;
}
final Size getPictureSize(int reference) {
final Size getPictureSize(@SuppressWarnings("SameParameterValue") int reference) {
if (mCaptureSize == null || mMode == Mode.VIDEO) return null;
return flip(REF_SENSOR, reference) ? mCaptureSize.flip() : mCaptureSize;
}
final Size getVideoSize(int reference) {
final Size getVideoSize(@SuppressWarnings("SameParameterValue") int reference) {
if (mCaptureSize == null || mMode == Mode.PICTURE) return null;
return flip(REF_SENSOR, reference) ? mCaptureSize.flip() : mCaptureSize;
}
@ -496,6 +506,8 @@ abstract class CameraController implements
* But when it does, the {@link CameraPreview.SurfaceCallback} should be called,
* and this should be refreshed.
*/
@NonNull
@SuppressWarnings("WeakerAccess")
protected final Size computeCaptureSize() {
// We want to pass stuff into the REF_VIEW reference, not the sensor one.
// This is already managed by CameraOptions, so we just flip again at the end.
@ -517,7 +529,9 @@ abstract class CameraController implements
return result;
}
protected final Size computePreviewSize(List<Size> previewSizes) {
@NonNull
@SuppressWarnings("WeakerAccess")
protected final Size computePreviewSize(@NonNull List<Size> previewSizes) {
// instead of flipping everything to REF_VIEW, we can just flip the
// surface size from REF_VIEW to REF_SENSOR, and reflip at the end.
AspectRatio targetRatio = AspectRatio.of(mCaptureSize.getWidth(), mCaptureSize.getHeight());

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
public abstract class CameraListener {
@ -14,7 +15,7 @@ public abstract class CameraListener {
* @param options camera supported options
*/
@UiThread
public void onCameraOpened(CameraOptions options) {
public void onCameraOpened(@NonNull CameraOptions options) {
}
@ -57,7 +58,7 @@ public abstract class CameraListener {
* @param result captured picture
*/
@UiThread
public void onPictureTaken(PictureResult result) {
public void onPictureTaken(@NonNull PictureResult result) {
}
@ -68,7 +69,7 @@ public abstract class CameraListener {
* @param result the video result
*/
@UiThread
public void onVideoTaken(VideoResult result) {
public void onVideoTaken(@NonNull VideoResult result) {
}
@ -97,7 +98,7 @@ public abstract class CameraListener {
* @param point coordinates with respect to CameraView.getWidth() and CameraView.getHeight()
*/
@UiThread
public void onFocusStart(PointF point) {
public void onFocusStart(@NonNull PointF point) {
}
@ -112,7 +113,7 @@ public abstract class CameraListener {
* @param point coordinates with respect to CameraView.getWidth() and CameraView.getHeight()
*/
@UiThread
public void onFocusEnd(boolean successful, PointF point) {
public void onFocusEnd(boolean successful, @NonNull PointF point) {
}
@ -123,10 +124,10 @@ public abstract class CameraListener {
*
* @param newValue the new zoom value
* @param bounds min and max bounds for newValue (fixed to 0 ... 1)
* @param fingers finger positions that caused the event
* @param fingers finger positions that caused the event, null if not caused by touch
*/
@UiThread
public void onZoomChanged(float newValue, float[] bounds, PointF[] fingers) {
public void onZoomChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers) {
}
@ -137,10 +138,10 @@ public abstract class CameraListener {
*
* @param newValue the new correction value
* @param bounds min and max bounds for newValue, as returned by {@link CameraOptions}
* @param fingers finger positions that caused the event
* @param fingers finger positions that caused the event, null if not caused by touch
*/
@UiThread
public void onExposureCorrectionChanged(float newValue, float[] bounds, PointF[] fingers) {
public void onExposureCorrectionChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers) {
}

@ -36,7 +36,7 @@ public class CameraOptions {
// Camera1 constructor.
@SuppressWarnings("deprecation")
CameraOptions(Camera.Parameters params, boolean flipSizes) {
CameraOptions(@NonNull Camera.Parameters params, boolean flipSizes) {
List<String> strings;
Mapper mapper = new Mapper1();
@ -107,7 +107,7 @@ public class CameraOptions {
// Camera2 constructor.
@TargetApi(21)
CameraOptions(CameraCharacteristics params) {}
CameraOptions(@NonNull CameraCharacteristics params) {}
/**
@ -116,7 +116,7 @@ public class CameraOptions {
* @param control value to check
* @return whether it's supported
*/
public boolean supports(Control control) {
public boolean supports(@NonNull Control control) {
return getSupportedControls(control.getClass()).contains(control);
}
@ -128,7 +128,7 @@ public class CameraOptions {
* @param action value to be checked
* @return whether it's supported
*/
public boolean supports(GestureAction action) {
public boolean supports(@NonNull GestureAction action) {
switch (action) {
case FOCUS:
case FOCUS_WITH_MARKER:
@ -146,6 +146,7 @@ public class CameraOptions {
@SuppressWarnings("unchecked")
@NonNull
public <T extends Control> Collection<T> getSupportedControls(@NonNull Class<T> controlClass) {
if (controlClass.equals(Audio.class)) {
return (Collection<T>) Arrays.asList(Audio.values());
@ -174,6 +175,7 @@ public class CameraOptions {
*
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<Size> getSupportedPictureSizes() {
return Collections.unmodifiableSet(supportedPictureSizes);
@ -185,6 +187,7 @@ public class CameraOptions {
*
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<AspectRatio> getSupportedPictureAspectRatios() {
return Collections.unmodifiableSet(supportedPictureAspectRatio);
@ -196,6 +199,7 @@ public class CameraOptions {
*
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<Size> getSupportedVideoSizes() {
return Collections.unmodifiableSet(supportedVideoSizes);
@ -207,6 +211,7 @@ public class CameraOptions {
*
* @return a set of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<AspectRatio> getSupportedVideoAspectRatios() {
return Collections.unmodifiableSet(supportedVideoAspectRatio);
@ -220,6 +225,7 @@ public class CameraOptions {
* @see Facing#FRONT
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<Facing> getSupportedFacing() {
return Collections.unmodifiableSet(supportedFacing);
@ -235,6 +241,7 @@ public class CameraOptions {
* @see Flash#TORCH
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<Flash> getSupportedFlash() {
return Collections.unmodifiableSet(supportedFlash);
@ -251,6 +258,7 @@ public class CameraOptions {
* @see WhiteBalance#CLOUDY
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<WhiteBalance> getSupportedWhiteBalance() {
return Collections.unmodifiableSet(supportedWhiteBalance);
@ -264,6 +272,7 @@ public class CameraOptions {
* @see Hdr#ON
* @return a collection of supported values.
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Collection<Hdr> getSupportedHdr() {
return Collections.unmodifiableSet(supportedHdr);
@ -275,6 +284,7 @@ public class CameraOptions {
*
* @return whether zoom is supported.
*/
@SuppressWarnings("WeakerAccess")
public boolean isZoomSupported() {
return zoomSupported;
}
@ -287,6 +297,7 @@ public class CameraOptions {
*
* @return whether auto focus is supported.
*/
@SuppressWarnings("WeakerAccess")
public boolean isAutoFocusSupported() {
return autoFocusSupported;
}
@ -300,6 +311,7 @@ public class CameraOptions {
* @see #getExposureCorrectionMaxValue()
* @return whether exposure correction is supported.
*/
@SuppressWarnings("WeakerAccess")
public boolean isExposureCorrectionSupported() {
return exposureCorrectionSupported;
}
@ -311,6 +323,7 @@ public class CameraOptions {
*
* @return min EV value
*/
@SuppressWarnings("WeakerAccess")
public float getExposureCorrectionMinValue() {
return exposureCorrectionMinValue;
}
@ -322,6 +335,7 @@ public class CameraOptions {
*
* @return max EV value
*/
@SuppressWarnings("WeakerAccess")
public float getExposureCorrectionMaxValue() {
return exposureCorrectionMaxValue;
}

@ -752,7 +752,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
float max = options.getExposureCorrectionMaxValue();
if (EVvalue < min) EVvalue = min;
if (EVvalue > max) EVvalue = max;
mCameraController.setExposureCorrection(EVvalue, null, null, false);
float[] bounds = new float[]{min, max};
mCameraController.setExposureCorrection(EVvalue, bounds, null, false);
}
}
@ -1561,10 +1562,10 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
void onShutter(boolean shouldPlaySound);
void dispatchOnVideoTaken(VideoResult result);
void dispatchOnPictureTaken(PictureResult result);
void dispatchOnFocusStart(@Nullable Gesture trigger, PointF where);
void dispatchOnFocusEnd(@Nullable Gesture trigger, boolean success, PointF where);
void dispatchOnZoomChanged(final float newValue, final PointF[] fingers);
void dispatchOnExposureCorrectionChanged(float newValue, float[] bounds, PointF[] fingers);
void dispatchOnFocusStart(@Nullable Gesture trigger, @NonNull PointF where);
void dispatchOnFocusEnd(@Nullable Gesture trigger, boolean success, @NonNull PointF where);
void dispatchOnZoomChanged(final float newValue, @Nullable final PointF[] fingers);
void dispatchOnExposureCorrectionChanged(float newValue, @NonNull float[] bounds, @Nullable PointF[] fingers);
void dispatchFrame(Frame frame);
void dispatchError(CameraException exception);
}
@ -1651,7 +1652,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
@Override
public void dispatchOnFocusStart(@Nullable final Gesture gesture, final PointF point) {
public void dispatchOnFocusStart(@Nullable final Gesture gesture, @NonNull final PointF point) {
mLogger.i("dispatchOnFocusStart", gesture, point);
mUiHandler.post(new Runnable() {
@Override
@ -1669,7 +1670,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@Override
public void dispatchOnFocusEnd(@Nullable final Gesture gesture, final boolean success,
final PointF point) {
@NonNull final PointF point) {
mLogger.i("dispatchOnFocusEnd", gesture, success, point);
mUiHandler.post(new Runnable() {
@Override
@ -1707,7 +1708,7 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
}
@Override
public void dispatchOnZoomChanged(final float newValue, final PointF[] fingers) {
public void dispatchOnZoomChanged(final float newValue, @Nullable final PointF[] fingers) {
mLogger.i("dispatchOnZoomChanged", newValue);
mUiHandler.post(new Runnable() {
@Override
@ -1721,8 +1722,8 @@ public class CameraView extends FrameLayout implements LifecycleObserver {
@Override
public void dispatchOnExposureCorrectionChanged(final float newValue,
final float[] bounds,
final PointF[] fingers) {
@NonNull final float[] bounds,
@Nullable final PointF[] fingers) {
mLogger.i("dispatchOnExposureCorrectionChanged", newValue);
mUiHandler.post(new Runnable() {
@Override

@ -1,6 +1,7 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* A preview frame to be processed by {@link FrameProcessor}s.
@ -19,7 +20,7 @@ public class Frame {
mManager = manager;
}
void set(byte[] data, long time, int rotation, Size size, int format) {
void set(@NonNull byte[] data, long time, int rotation, @NonNull Size size, int format) {
this.mData = data;
this.mTime = time;
this.mRotation = rotation;
@ -40,6 +41,8 @@ public class Frame {
*
* @return a frozen Frame
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public Frame freeze() {
byte[] data = new byte[mData.length];
System.arraycopy(mData, 0, data, 0, mData.length);
@ -74,6 +77,7 @@ public class Frame {
* Returns the frame data.
* @return the frame data
*/
@NonNull
public byte[] getData() {
return mData;
}
@ -104,6 +108,7 @@ public class Frame {
*
* @return frame size
*/
@NonNull
public Size getSize() {
return mSize;
}

@ -1,6 +1,9 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.util.concurrent.LinkedBlockingQueue;
/**
@ -21,7 +24,7 @@ import java.util.concurrent.LinkedBlockingQueue;
class FrameManager {
interface BufferCallback {
void onBufferAvailable(byte[] buffer);
void onBufferAvailable(@NonNull byte[] buffer);
}
private int mPoolSize;
@ -29,7 +32,7 @@ class FrameManager {
private BufferCallback mCallback;
private LinkedBlockingQueue<Frame> mQueue;
FrameManager(int poolSize, BufferCallback callback) {
FrameManager(int poolSize, @Nullable BufferCallback callback) {
mPoolSize = poolSize;
mCallback = callback;
mQueue = new LinkedBlockingQueue<>(mPoolSize);
@ -71,14 +74,14 @@ class FrameManager {
*
* @return a new frame
*/
Frame getFrame(byte[] data, long time, int rotation, Size previewSize, int previewFormat) {
Frame getFrame(@NonNull byte[] data, long time, int rotation, @NonNull Size previewSize, int previewFormat) {
Frame frame = mQueue.poll();
if (frame == null) frame = new Frame(this);
frame.set(data, time, rotation, previewSize, previewFormat);
return frame;
}
int allocate(int bitsPerPixel, Size previewSize) {
int allocate(int bitsPerPixel, @NonNull Size previewSize) {
mBufferSize = getBufferSize(bitsPerPixel, previewSize);
for (int i = 0; i < mPoolSize; i++) {
mCallback.onBufferAvailable(new byte[mBufferSize]);
@ -86,7 +89,7 @@ class FrameManager {
return mBufferSize;
}
private int getBufferSize(int bitsPerPixel, Size previewSize) {
private int getBufferSize(int bitsPerPixel, @NonNull Size previewSize) {
long sizeInBits = previewSize.getHeight() * previewSize.getWidth() * bitsPerPixel;
return (int) Math.ceil(sizeInBits / 8.0d);
}

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.hardware.Camera;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.media.ExifInterface;
import java.io.ByteArrayInputStream;
@ -16,7 +18,7 @@ class FullPictureRecorder extends PictureRecorder {
private Camera mCamera;
FullPictureRecorder(PictureResult stub, PictureResultListener listener, Camera camera) {
FullPictureRecorder(@NonNull PictureResult stub, @Nullable PictureResultListener listener, @NonNull Camera camera) {
super(stub, listener);
mCamera = camera;

@ -3,6 +3,8 @@ package com.otaliastudios.cameraview;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* A {@link VideoRecorder} that uses {@link android.media.MediaRecorder} APIs.
@ -15,7 +17,7 @@ class FullVideoRecorder extends VideoRecorder {
private MediaRecorder mMediaRecorder;
private CamcorderProfile mProfile;
FullVideoRecorder(VideoResult stub, VideoResultListener listener, Camera camera, int cameraId) {
FullVideoRecorder(@NonNull VideoResult stub, @Nullable VideoResultListener listener, @NonNull Camera camera, int cameraId) {
super(stub, listener);
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setCamera(camera);

@ -1,5 +1,6 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
@ -12,13 +13,14 @@ abstract class PictureRecorder {
/* tests */ PictureResult mResult;
/* tests */ PictureResultListener mListener;
PictureRecorder(PictureResult stub, PictureResultListener listener) {
PictureRecorder(@NonNull PictureResult stub, @Nullable PictureResultListener listener) {
mResult = stub;
mListener = listener;
}
abstract void take();
@SuppressWarnings("WeakerAccess")
protected void dispatchOnShutter(boolean didPlaySound) {
if (mListener != null) mListener.onPictureShutter(didPlaySound);
}

@ -93,7 +93,7 @@ public class PictureResult {
* @param maxHeight the max. height of final bitmap
* @param callback a callback to be notified of image decoding
*/
public void asBitmap(int maxWidth, int maxHeight, BitmapCallback callback) {
public void asBitmap(int maxWidth, int maxHeight, @NonNull BitmapCallback callback) {
CameraUtils.decodeBitmap(getData(), maxWidth, maxHeight, rotation, callback);
}
@ -104,7 +104,9 @@ public class PictureResult {
*
* @param callback a callback to be notified of image decoding
*/
public void asBitmap(BitmapCallback callback) {
public void asBitmap(@NonNull BitmapCallback callback) {
asBitmap(-1, -1, callback);
}
// TODO toFile
}

@ -10,6 +10,7 @@ import android.hardware.Camera;
import android.opengl.EGL14;
import android.opengl.EGLContext;
import android.opengl.Matrix;
import android.support.annotation.NonNull;
import java.io.ByteArrayOutputStream;
@ -28,7 +29,8 @@ class SnapshotPictureRecorder extends PictureRecorder {
private Size mSensorPreviewSize;
private int mFormat;
SnapshotPictureRecorder(PictureResult stub, Camera1 controller, Camera camera, AspectRatio outputRatio) {
SnapshotPictureRecorder(@NonNull PictureResult stub, @NonNull Camera1 controller,
@NonNull Camera camera, @NonNull AspectRatio outputRatio) {
super(stub, controller);
mController = controller;
mPreview = controller.mPreview;
@ -48,7 +50,7 @@ class SnapshotPictureRecorder extends PictureRecorder {
}
@SuppressLint("NewApi")
private void takeGl(final GlCameraPreview preview) {
private void takeGl(@NonNull final GlCameraPreview preview) {
preview.addRendererFrameCallback(new GlCameraPreview.RendererFrameCallback() {
int mTextureId;
@ -145,7 +147,7 @@ class SnapshotPictureRecorder extends PictureRecorder {
private void takeLegacy() {
mCamera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(final byte[] yuv, Camera camera) {
public void onPreviewFrame(@NonNull final byte[] yuv, Camera camera) {
dispatchOnShutter(false);
// Got to rotate the preview frame, since byte[] data here does not include

@ -4,6 +4,7 @@ import android.graphics.SurfaceTexture;
import android.opengl.EGL14;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
@ -31,7 +32,7 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
private int mDesiredState = STATE_NOT_RECORDING;
private int mTextureId = 0;
SnapshotVideoRecorder(VideoResult stub, VideoResultListener listener, GlCameraPreview preview) {
SnapshotVideoRecorder(@NonNull VideoResult stub, @Nullable VideoResultListener listener, @NonNull GlCameraPreview preview) {
super(stub, listener);
mPreview = preview;
mPreview.addRendererFrameCallback(this);
@ -55,7 +56,7 @@ class SnapshotVideoRecorder extends VideoRecorder implements GlCameraPreview.Ren
@RendererThread
@Override
public void onRendererFrame(SurfaceTexture surfaceTexture, float scaleX, float scaleY) {
public void onRendererFrame(@NonNull SurfaceTexture surfaceTexture, float scaleX, float scaleY) {
if (mCurrentState == STATE_NOT_RECORDING && mDesiredState == STATE_RECORDING) {
Size size = mResult.getSize();
// Ensure width and height are divisible by 2, as I have read somewhere.

@ -1,5 +1,6 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.io.File;
@ -14,7 +15,7 @@ abstract class VideoRecorder {
/* tests */ VideoResult mResult;
/* tests */ VideoResultListener mListener;
VideoRecorder(VideoResult stub, VideoResultListener listener) {
VideoRecorder(@NonNull VideoResult stub, @Nullable VideoResultListener listener) {
mResult = stub;
mListener = listener;
}

@ -11,8 +11,13 @@ import java.io.File;
*/
public class VideoResult {
@SuppressWarnings({"WeakerAccess", "unused"})
public static final int REASON_USER = 0;
@SuppressWarnings("WeakerAccess")
public static final int REASON_MAX_SIZE_REACHED = 1;
@SuppressWarnings("WeakerAccess")
public static final int REASON_MAX_DURATION_REACHED = 2;
boolean isSnapshot;

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* Audio values indicate whether to record audio stream when record video.
*
@ -30,6 +32,7 @@ public enum Audio implements Control {
return value;
}
@Nullable
static Audio fromValue(int value) {
Audio[] list = Audio.values();
for (Audio action : list) {

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
@ -21,7 +22,8 @@ public enum Facing implements Control {
*/
FRONT(1);
final static Facing DEFAULT(@Nullable Context context) {
@NonNull
static Facing DEFAULT(@Nullable Context context) {
if (context == null) {
return BACK;
} else if (CameraUtils.hasCameraFacing(context, BACK)) {
@ -45,6 +47,7 @@ public enum Facing implements Control {
return value;
}
@Nullable
static Facing fromValue(int value) {
Facing[] list = Facing.values();
for (Facing action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* Flash value indicates the flash mode to be used.
*
@ -51,6 +53,7 @@ public enum Flash implements Control {
return value;
}
@Nullable
static Flash fromValue(int value) {
Flash[] list = Flash.values();
for (Flash action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* Gestures actions are actions over camera controls that can be mapped to certain gestures over
* the screen, using XML attributes or {@link CameraView#mapGesture(Gesture, GestureAction)}.
@ -81,6 +83,7 @@ public enum GestureAction {
return value;
}
@Nullable
static GestureAction fromValue(int value) {
GestureAction[] list = GestureAction.values();
for (GestureAction action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* Grid values can be used to draw grid lines over the camera preview.
*
@ -42,6 +44,7 @@ public enum Grid implements Control {
return value;
}
@Nullable
static Grid fromValue(int value) {
Grid[] list = Grid.values();
for (Grid action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* Hdr values indicate whether to use high dynamic range techniques when capturing pictures.
*
@ -30,6 +32,7 @@ public enum Hdr implements Control {
return value;
}
@Nullable
static Hdr fromValue(int value) {
Hdr[] list = Hdr.values();
for (Hdr action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
import java.io.File;
/**
@ -42,6 +44,7 @@ public enum Mode implements Control {
return value;
}
@Nullable
static Mode fromValue(int value) {
Mode[] list = Mode.values();
for (Mode action : list) {

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* The preview engine to be used.
*
@ -40,6 +42,7 @@ public enum Preview implements Control {
return value;
}
@Nullable
static Preview fromValue(int value) {
Preview[] list = Preview.values();
for (Preview action : list) {

@ -1,6 +1,9 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
/**
* Constants for selecting the encoder of video recordings.
* https://developer.android.com/guide/topics/media/media-formats.html#video-formats
@ -37,6 +40,7 @@ public enum VideoCodec implements Control {
return value;
}
@Nullable
static VideoCodec fromValue(int value) {
VideoCodec[] list = VideoCodec.values();
for (VideoCodec action : list) {

@ -1,6 +1,7 @@
package com.otaliastudios.cameraview;
import android.support.annotation.Nullable;
/**
* White balance values control the white balance settings.
@ -61,6 +62,7 @@ public enum WhiteBalance implements Control {
return value;
}
@Nullable
static WhiteBalance fromValue(int value) {
WhiteBalance[] list = WhiteBalance.values();
for (WhiteBalance action : list) {

@ -1,6 +1,7 @@
package com.otaliastudios.cameraview;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
@ -45,7 +46,7 @@ public final class CameraLogger {
* @param message the log message
* @param throwable an optional throwable
*/
void log(@LogLevel int level, String tag, String message, @Nullable Throwable throwable);
void log(@LogLevel int level, @NonNull String tag, @NonNull String message, @Nullable Throwable throwable);
}
static String lastMessage;
@ -59,7 +60,7 @@ public final class CameraLogger {
sLoggers = new ArrayList<>();
sLoggers.add(new Logger() {
@Override
public void log(int level, String tag, String message, @Nullable Throwable throwable) {
public void log(int level, @NonNull String tag, @NonNull String message, @Nullable Throwable throwable) {
switch (level) {
case LEVEL_VERBOSE: Log.v(tag, message, throwable); break;
case LEVEL_INFO: Log.i(tag, message, throwable); break;
@ -70,7 +71,7 @@ public final class CameraLogger {
});
}
static CameraLogger create(String tag) {
static CameraLogger create(@NonNull String tag) {
return new CameraLogger(tag);
}
@ -93,7 +94,8 @@ public final class CameraLogger {
*
* @param logger logger to add
*/
public static void registerLogger(Logger logger) {
@SuppressWarnings("WeakerAccess")
public static void registerLogger(@NonNull Logger logger) {
sLoggers.add(logger);
}
@ -103,13 +105,15 @@ public final class CameraLogger {
*
* @param logger logger to remove
*/
public static void unregisterLogger(Logger logger) {
@SuppressWarnings("WeakerAccess")
public static void unregisterLogger(@NonNull Logger logger) {
sLoggers.remove(logger);
}
@NonNull
private String mTag;
private CameraLogger(String tag) {
private CameraLogger(@NonNull String tag) {
mTag = tag;
}
@ -117,41 +121,39 @@ public final class CameraLogger {
return sLevel <= messageLevel && sLoggers.size() > 0;
}
void v(Object... data) {
void v(@NonNull Object... data) {
log(LEVEL_VERBOSE, data);
}
void i(Object... data) {
void i(@NonNull Object... data) {
log(LEVEL_INFO, data);
}
void w(Object... data) {
void w(@NonNull Object... data) {
log(LEVEL_WARNING, data);
}
void e(Object... data) {
void e(@NonNull Object... data) {
log(LEVEL_ERROR, data);
}
private void log(@LogLevel int level, Object... data) {
private void log(@LogLevel int level, @NonNull Object... data) {
if (!should(level)) return;
String message = "";
StringBuilder message = new StringBuilder();
Throwable throwable = null;
final int size = data.length;
for (Object object : data) {
if (object instanceof Throwable) {
throwable = (Throwable) object;
}
message += String.valueOf(object);
message += " ";
message.append(String.valueOf(object));
message.append(" ");
}
message = message.trim();
for (Logger logger : sLoggers) {
logger.log(level, mTag, message, throwable);
logger.log(level, mTag, message.toString().trim(), throwable);
}
lastMessage = message;
lastMessage = message.toString();
lastTag = mTag;
}
}

@ -30,7 +30,7 @@ public class CameraUtils {
* @return whether device has cameras
*/
@SuppressWarnings("WeakerAccess")
public static boolean hasCameras(Context context) {
public static boolean hasCameras(@NonNull Context context) {
PackageManager manager = context.getPackageManager();
// There's also FEATURE_CAMERA_EXTERNAL , should we support it?
return manager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
@ -46,7 +46,7 @@ public class CameraUtils {
* @param facing either {@link Facing#BACK} or {@link Facing#FRONT}
* @return true if such sensor exists
*/
public static boolean hasCameraFacing(Context context, Facing facing) {
public static boolean hasCameraFacing(@NonNull Context context, @NonNull Facing facing) {
int internal = new Mapper1().map(facing);
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0, count = Camera.getNumberOfCameras(); i < count; i++) {
@ -66,7 +66,7 @@ public class CameraUtils {
*/
@SuppressWarnings("WeakerAccess")
@WorkerThread
public static void decodeBitmap(final byte[] source) {
public static void decodeBitmap(@NonNull final byte[] source) {
decodeBitmap(source, Integer.MAX_VALUE, Integer.MAX_VALUE);
}
@ -80,7 +80,7 @@ public class CameraUtils {
* @param callback a callback to be notified
*/
@SuppressWarnings("WeakerAccess")
public static void decodeBitmap(final byte[] source, final BitmapCallback callback) {
public static void decodeBitmap(@NonNull final byte[] source, @NonNull final BitmapCallback callback) {
decodeBitmap(source, Integer.MAX_VALUE, Integer.MAX_VALUE, callback);
}
@ -98,7 +98,7 @@ public class CameraUtils {
* @param callback a callback to be notified
*/
@SuppressWarnings("WeakerAccess")
public static void decodeBitmap(final byte[] source, final int maxWidth, final int maxHeight, final BitmapCallback callback) {
public static void decodeBitmap(@NonNull final byte[] source, final int maxWidth, final int maxHeight, @NonNull final BitmapCallback callback) {
decodeBitmap(source, maxWidth, maxHeight, new BitmapFactory.Options(), callback);
}
@ -117,12 +117,12 @@ public class CameraUtils {
* @param callback a callback to be notified
*/
@SuppressWarnings("WeakerAccess")
public static void decodeBitmap(final byte[] source, final int maxWidth, final int maxHeight, @NonNull final BitmapFactory.Options options, final BitmapCallback callback) {
public static void decodeBitmap(@NonNull final byte[] source, final int maxWidth, final int maxHeight, @NonNull final BitmapFactory.Options options, @NonNull final BitmapCallback callback) {
decodeBitmap(source, maxWidth, maxHeight, options, -1, callback);
}
@SuppressWarnings("WeakerAccess")
static void decodeBitmap(final byte[] source, final int maxWidth, final int maxHeight, @NonNull final BitmapFactory.Options options, final int rotation, final BitmapCallback callback) {
static void decodeBitmap(@NonNull final byte[] source, final int maxWidth, final int maxHeight, @NonNull final BitmapFactory.Options options, final int rotation, @NonNull final BitmapCallback callback) {
final Handler ui = new Handler();
WorkerHandler.run(new Runnable() {
@Override
@ -149,7 +149,7 @@ public class CameraUtils {
* @param maxWidth the max allowed width
* @param maxHeight the max allowed height
*/
static Bitmap decodeBitmap(byte[] source, int maxWidth, int maxHeight) {
static Bitmap decodeBitmap(@NonNull byte[] source, int maxWidth, int maxHeight) {
return decodeBitmap(source, maxWidth, maxHeight, new BitmapFactory.Options());
}
@ -168,14 +168,14 @@ public class CameraUtils {
@SuppressWarnings({"SuspiciousNameCombination", "WeakerAccess"})
@Nullable
@WorkerThread
public static Bitmap decodeBitmap(byte[] source, int maxWidth, int maxHeight, @NonNull BitmapFactory.Options options) {
public static Bitmap decodeBitmap(@NonNull byte[] source, int maxWidth, int maxHeight, @NonNull BitmapFactory.Options options) {
return decodeBitmap(source, maxWidth, maxHeight, options, -1);
}
// Null: got OOM
// TODO ignores flipping. but it should be super rare.
@Nullable
static Bitmap decodeBitmap(byte[] source, int maxWidth, int maxHeight, @NonNull BitmapFactory.Options options, int rotation) {
static Bitmap decodeBitmap(@NonNull byte[] source, int maxWidth, int maxHeight, @NonNull BitmapFactory.Options options, int rotation) {
if (maxWidth <= 0) maxWidth = Integer.MAX_VALUE;
if (maxHeight <= 0) maxHeight = Integer.MAX_VALUE;
int orientation;
@ -220,6 +220,7 @@ public class CameraUtils {
if (orientation % 180 != 0) {
//noinspection SuspiciousNameCombination
outHeight = options.outWidth;
//noinspection SuspiciousNameCombination
outWidth = options.outHeight;
}

@ -1,11 +1,13 @@
package com.otaliastudios.cameraview;
import android.graphics.Rect;
import android.support.annotation.NonNull;
class CropHelper {
// It's important that size and aspect ratio belong to the same reference.
static Rect computeCrop(Size currentSize, AspectRatio targetRatio) {
@NonNull
static Rect computeCrop(@NonNull Size currentSize, @NonNull AspectRatio targetRatio) {
int currentWidth = currentSize.getWidth();
int currentHeight = currentSize.getHeight();
if (targetRatio.matches(currentSize)) {

@ -20,10 +20,11 @@ class OrientationHelper {
void onDeviceOrientationChanged(int deviceOrientation);
}
OrientationHelper(Context context, @NonNull Callback callback) {
OrientationHelper(@NonNull Context context, @NonNull Callback callback) {
mCallback = callback;
mListener = new OrientationEventListener(context.getApplicationContext(), SensorManager.SENSOR_DELAY_NORMAL) {
@SuppressWarnings("ConstantConditions")
@Override
public void onOrientationChanged(int orientation) {
int or = 0;
@ -47,7 +48,7 @@ class OrientationHelper {
};
}
void enable(Context context) {
void enable(@NonNull Context context) {
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
switch (display.getRotation()) {
case Surface.ROTATION_0: mDisplayOffset = 0; break;

@ -1,10 +1,17 @@
package com.otaliastudios.cameraview;
import android.graphics.Rect;
import android.support.annotation.NonNull;
/**
* This will only be used on low APIs or when GL surface is not available.
* This risks OOMs and was never a good tool.
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
class RotationHelper {
static byte[] rotate(final byte[] yuv, final Size size, final int rotation) {
static byte[] rotate(@NonNull final byte[] yuv, @NonNull final Size size, final int rotation) {
if (rotation == 0) return yuv;
if (rotation % 90 != 0 || rotation < 0 || rotation > 270) {
throw new IllegalArgumentException("0 <= rotation < 360, rotation % 90 == 0");

@ -16,7 +16,7 @@ public class SizeSelectors {
* sizes in a list.
*/
public interface Filter {
boolean accepts(Size size);
boolean accepts(@NonNull Size size);
}
/**
@ -26,6 +26,8 @@ public class SizeSelectors {
* @param filter a filter
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector withFilter(@NonNull Filter filter) {
return new FilterSelector(filter);
}
@ -37,10 +39,11 @@ public class SizeSelectors {
* @param width the max width
* @return a new selector
*/
@NonNull
public static SizeSelector maxWidth(final int width) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getWidth() <= width;
}
});
@ -53,10 +56,11 @@ public class SizeSelectors {
* @param width the min width
* @return a new selector
*/
@NonNull
public static SizeSelector minWidth(final int width) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getWidth() >= width;
}
});
@ -69,10 +73,12 @@ public class SizeSelectors {
* @param height the max height
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector maxHeight(final int height) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getHeight() <= height;
}
});
@ -85,10 +91,11 @@ public class SizeSelectors {
* @param height the min height
* @return a new selector
*/
@NonNull
public static SizeSelector minHeight(final int height) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getHeight() >= height;
}
});
@ -103,11 +110,13 @@ public class SizeSelectors {
* @param delta a small tolerance value
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector aspectRatio(AspectRatio ratio, final float delta) {
final float desired = ratio.toFloat();
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
float candidate = AspectRatio.of(size.getWidth(), size.getHeight()).toFloat();
return candidate >= desired - delta && candidate <= desired + delta;
}
@ -120,6 +129,8 @@ public class SizeSelectors {
*
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector biggest() {
return new SizeSelector() {
@NonNull
@ -138,6 +149,8 @@ public class SizeSelectors {
*
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector smallest() {
return new SizeSelector() {
@NonNull
@ -156,10 +169,12 @@ public class SizeSelectors {
* @param area the max area
* @return a new selector
*/
@NonNull
@SuppressWarnings("WeakerAccess")
public static SizeSelector maxArea(final int area) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getHeight() * size.getWidth() <= area;
}
});
@ -172,10 +187,12 @@ public class SizeSelectors {
* @param area the min area
* @return a new selector
*/
@SuppressWarnings("WeakerAccess")
@NonNull
public static SizeSelector minArea(final int area) {
return withFilter(new Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getHeight() * size.getWidth() >= area;
}
});
@ -191,6 +208,7 @@ public class SizeSelectors {
* @param selectors input selectors
* @return a new selector
*/
@NonNull
public static SizeSelector and(SizeSelector... selectors) {
return new AndSelector(selectors);
}
@ -203,6 +221,7 @@ public class SizeSelectors {
* @param selectors input selectors
* @return a new selector
*/
@NonNull
public static SizeSelector or(SizeSelector... selectors) {
return new OrSelector(selectors);
}

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.NonNull;
import java.lang.ref.WeakReference;
import java.util.WeakHashMap;
@ -16,7 +17,8 @@ class WorkerHandler {
private final static CameraLogger LOG = CameraLogger.create(WorkerHandler.class.getSimpleName());
private final static ConcurrentHashMap<String, WeakReference<WorkerHandler>> sCache = new ConcurrentHashMap<>(4);
public static WorkerHandler get(String name) {
@NonNull
public static WorkerHandler get(@NonNull String name) {
if (sCache.containsKey(name)) {
WorkerHandler cached = sCache.get(name).get();
if (cached != null) {
@ -39,14 +41,14 @@ class WorkerHandler {
// Handy util to perform action in a fallback thread.
// Not to be used for long-running operations since they will
// block the fallback thread.
public static void run(Runnable action) {
public static void run(@NonNull Runnable action) {
get("FallbackCameraThread").post(action);
}
private HandlerThread mThread;
private Handler mHandler;
private WorkerHandler(String name) {
private WorkerHandler(@NonNull String name) {
mThread = new HandlerThread(name);
mThread.setDaemon(true);
mThread.start();
@ -57,15 +59,16 @@ class WorkerHandler {
return mHandler;
}
public void post(Runnable runnable) {
public void post(@NonNull Runnable runnable) {
mHandler.post(runnable);
}
@NonNull
public Thread getThread() {
return mThread;
}
public static void destroy() {
static void destroy() {
for (String key : sCache.keySet()) {
WeakReference<WorkerHandler> ref = sCache.get(key);
WorkerHandler handler = ref.get();

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
import android.view.ViewGroup;
@ -33,21 +34,23 @@ abstract class CameraPreview<T extends View, Output> {
protected int mInputStreamHeight;
protected boolean mInputFlipped;
CameraPreview(Context context, ViewGroup parent, SurfaceCallback callback) {
CameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
mView = onCreateView(context, parent);
mSurfaceCallback = callback;
}
@NonNull
protected abstract T onCreateView(Context context, ViewGroup parent);
protected abstract T onCreateView(@NonNull Context context, @NonNull ViewGroup parent);
@NonNull
final T getView() {
return mView;
}
@NonNull
abstract Class<Output> getOutputClass();
@NonNull
abstract Output getOutput();
// As far as I can see, these are the actual preview dimensions, as set in CameraParameters.
@ -63,15 +66,17 @@ abstract class CameraPreview<T extends View, Output> {
}
}
@NonNull
final Size getInputStreamSize() {
return new Size(mInputStreamWidth, mInputStreamHeight);
}
@NonNull
final Size getOutputSurfaceSize() {
return new Size(mOutputSurfaceWidth, mOutputSurfaceHeight);
}
final void setSurfaceCallback(SurfaceCallback callback) {
final void setSurfaceCallback(@NonNull SurfaceCallback callback) {
mSurfaceCallback = callback;
// If surface already available, dispatch.
if (mOutputSurfaceWidth != 0 || mOutputSurfaceHeight != 0) {
@ -80,6 +85,7 @@ abstract class CameraPreview<T extends View, Output> {
}
@SuppressWarnings("WeakerAccess")
protected final void dispatchOnOutputSurfaceAvailable(int width, int height) {
LOG.i("dispatchOnOutputSurfaceAvailable:", "w=", width, "h=", height);
mOutputSurfaceWidth = width;
@ -93,6 +99,7 @@ abstract class CameraPreview<T extends View, Output> {
// As far as I can see, these are the view/surface dimensions.
// This is called by subclasses.
@SuppressWarnings("WeakerAccess")
protected final void dispatchOnOutputSurfaceSizeChanged(int width, int height) {
LOG.i("dispatchOnOutputSurfaceSizeChanged:", "w=", width, "h=", height);
if (width != mOutputSurfaceWidth || height != mOutputSurfaceHeight) {
@ -105,6 +112,7 @@ abstract class CameraPreview<T extends View, Output> {
}
}
@SuppressWarnings("WeakerAccess")
protected final void dispatchOnOutputSurfaceDestroyed() {
mOutputSurfaceWidth = 0;
mOutputSurfaceHeight = 0;

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.content.Context;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@ -17,12 +18,12 @@ abstract class GestureLayout extends FrameLayout {
protected Gesture mType;
protected PointF[] mPoints;
public GestureLayout(Context context) {
public GestureLayout(@NonNull Context context) {
super(context);
onInitialize(context);
}
protected void onInitialize(Context context) {
protected void onInitialize(@NonNull Context context) {
}
public void enable(boolean enable) {
@ -35,15 +36,17 @@ abstract class GestureLayout extends FrameLayout {
public abstract boolean onTouchEvent(MotionEvent event);
@NonNull
public final Gesture getGestureType() {
return mType;
}
// For tests.
void setGestureType(Gesture type) {
void setGestureType(@NonNull Gesture type) {
mType = type;
}
@NonNull
public final PointF[] getPoints() {
return mPoints;
}

@ -71,7 +71,7 @@ class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture> imple
/* for tests */ float mScaleY = 1F;
private float[] mScaleXY = new float[] { mScaleX, mScaleY };
GlCameraPreview(Context context, ViewGroup parent, SurfaceCallback callback) {
GlCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback);
}
@ -103,7 +103,7 @@ class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture> imple
@NonNull
@Override
protected GLSurfaceView onCreateView(Context context, ViewGroup parent) {
protected GLSurfaceView onCreateView(@NonNull Context context, @NonNull ViewGroup parent) {
ViewGroup root = (ViewGroup) LayoutInflater.from(context).inflate(R.layout.cameraview_gl_view, parent, false);
GLSurfaceView glView = root.findViewById(R.id.gl_surface_view);
glView.setEGLContextClientVersion(2);
@ -236,11 +236,13 @@ class GlCameraPreview extends CameraPreview<GLSurfaceView, SurfaceTexture> imple
}
}
@NonNull
@Override
Class<SurfaceTexture> getOutputClass() {
return SurfaceTexture.class;
}
@NonNull
@Override
SurfaceTexture getOutput() {
return mInputSurfaceTexture;

@ -26,7 +26,6 @@ class GridLinesLayout extends View {
Task<Integer> drawTask = new Task<>();
public GridLinesLayout(@NonNull Context context) {
this(context, null);
}
@ -45,11 +44,12 @@ class GridLinesLayout extends View {
vert.setBounds(0, top, (int) width, bottom);
}
@NonNull
public Grid getGridMode() {
return gridMode;
}
public void setGridMode(Grid gridMode) {
public void setGridMode(@NonNull Grid gridMode) {
this.gridMode = gridMode;
postInvalidate();
}
@ -89,7 +89,7 @@ class GridLinesLayout extends View {
}
@Override
protected void onDraw(Canvas canvas) {
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
drawTask.start();
int count = getLineCount();

@ -1,8 +1,10 @@
package com.otaliastudios.cameraview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PointF;
import android.os.Build;
import android.support.annotation.NonNull;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
@ -14,14 +16,12 @@ class PinchGestureLayout extends GestureLayout {
private boolean mNotify;
/* tests */ float mFactor = 0;
public PinchGestureLayout(Context context) {
public PinchGestureLayout(@NonNull Context context) {
super(context);
}
@Override
protected void onInitialize(Context context) {
protected void onInitialize(@NonNull Context context) {
super.onInitialize(context);
mPoints = new PointF[]{ new PointF(0, 0), new PointF(0, 0) };
mDetector = new ScaleGestureDetector(context, new ScaleGestureDetector.SimpleOnScaleGestureListener() {
@ -42,6 +42,7 @@ class PinchGestureLayout extends GestureLayout {
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mEnabled) return false;

@ -1,7 +1,9 @@
package com.otaliastudios.cameraview;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.view.GestureDetector;
import android.view.MotionEvent;
@ -14,13 +16,12 @@ class ScrollGestureLayout extends GestureLayout {
private boolean mNotify;
/* tests */ float mFactor;
public ScrollGestureLayout(Context context) {
public ScrollGestureLayout(@NonNull Context context) {
super(context);
}
@Override
protected void onInitialize(Context context) {
protected void onInitialize(@NonNull Context context) {
super.onInitialize(context);
mPoints = new PointF[]{ new PointF(0, 0), new PointF(0, 0) };
mDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@ -51,7 +52,7 @@ class ScrollGestureLayout extends GestureLayout {
mDetector.setIsLongpressEnabled(false); // Looks important.
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mEnabled) return false;
@ -71,7 +72,6 @@ class ScrollGestureLayout extends GestureLayout {
return mNotify;
}
@Override
public float scaleValue(float currValue, float minValue, float maxValue) {
float delta = mFactor; // -1 ... 1

@ -2,6 +2,7 @@ package com.otaliastudios.cameraview;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@ -18,13 +19,13 @@ class SurfaceCameraPreview extends CameraPreview<SurfaceView, SurfaceHolder> {
private boolean mDispatched;
SurfaceCameraPreview(Context context, ViewGroup parent, SurfaceCallback callback) {
SurfaceCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback);
}
@NonNull
@Override
protected SurfaceView onCreateView(Context context, ViewGroup parent) {
protected SurfaceView onCreateView(@NonNull Context context, @NonNull ViewGroup parent) {
View root = LayoutInflater.from(context).inflate(R.layout.cameraview_surface_view, parent, false);
parent.addView(root, 0);
SurfaceView surfaceView = root.findViewById(R.id.surface_view);
@ -59,11 +60,13 @@ class SurfaceCameraPreview extends CameraPreview<SurfaceView, SurfaceHolder> {
return surfaceView;
}
@NonNull
@Override
SurfaceHolder getOutput() {
return getView().getHolder();
}
@NonNull
@Override
Class<SurfaceHolder> getOutputClass() {
return SurfaceHolder.class;

@ -2,8 +2,11 @@ package com.otaliastudios.cameraview;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PointF;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.GestureDetector;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@ -13,20 +16,18 @@ import android.widget.ImageView;
class TapGestureLayout extends GestureLayout {
private GestureDetector mDetector;
private boolean mNotify;
private FrameLayout mFocusMarkerContainer;
private ImageView mFocusMarkerFill;
public TapGestureLayout(Context context) {
public TapGestureLayout(@NonNull Context context) {
super(context);
}
@Override
protected void onInitialize(Context context) {
protected void onInitialize(@NonNull Context context) {
super.onInitialize(context);
mPoints = new PointF[]{ new PointF(0, 0) };
mDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@ -62,7 +63,7 @@ class TapGestureLayout extends GestureLayout {
mFocusMarkerFill = findViewById(R.id.fill);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!mEnabled) return false;
@ -100,7 +101,7 @@ class TapGestureLayout extends GestureLayout {
}
};
public void onFocusStart(PointF point) {
public void onFocusStart(@NonNull PointF point) {
removeCallbacks(mFocusMarkerHideRunnable);
mFocusMarkerContainer.clearAnimation(); // animate().setListener(null).cancel();
mFocusMarkerFill.clearAnimation(); // animate().setListener(null).cancel();
@ -128,7 +129,6 @@ class TapGestureLayout extends GestureLayout {
});
}
public void onFocusEnd(boolean success) {
if (success) {
animate(mFocusMarkerContainer, 1, 0, 500, 0, null);
@ -145,9 +145,8 @@ class TapGestureLayout extends GestureLayout {
}
}
private static void animate(View view, float scale, float alpha, long duration, long delay,
Animator.AnimatorListener listener) {
private static void animate(@NonNull View view, float scale, float alpha, long duration, long delay,
@Nullable Animator.AnimatorListener listener) {
view.animate().scaleX(scale).scaleY(scale)
.alpha(alpha)
.setDuration(duration)

@ -4,6 +4,7 @@ import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
@ -11,13 +12,13 @@ import android.view.ViewGroup;
class TextureCameraPreview extends CameraPreview<TextureView, SurfaceTexture> {
TextureCameraPreview(Context context, ViewGroup parent, SurfaceCallback callback) {
TextureCameraPreview(@NonNull Context context, @NonNull ViewGroup parent, @Nullable SurfaceCallback callback) {
super(context, parent, callback);
}
@NonNull
@Override
protected TextureView onCreateView(Context context, ViewGroup parent) {
protected TextureView onCreateView(@NonNull Context context, @NonNull ViewGroup parent) {
View root = LayoutInflater.from(context).inflate(R.layout.cameraview_texture_view, parent, false);
parent.addView(root, 0);
TextureView texture = root.findViewById(R.id.texture_view);
@ -46,11 +47,13 @@ class TextureCameraPreview extends CameraPreview<TextureView, SurfaceTexture> {
return texture;
}
@NonNull
@Override
Class<SurfaceTexture> getOutputClass() {
return SurfaceTexture.class;
}
@NonNull
@Override
SurfaceTexture getOutput() {
return getView().getSurfaceTexture();

@ -1,6 +1,8 @@
package com.otaliastudios.cameraview;
import android.support.annotation.NonNull;
import org.junit.Before;
import org.junit.Test;
@ -33,7 +35,7 @@ public class SizeSelectorsTest {
public void testWithFilter() {
SizeSelector selector = SizeSelectors.withFilter(new SizeSelectors.Filter() {
@Override
public boolean accepts(Size size) {
public boolean accepts(@NonNull Size size) {
return size.getWidth() == 600;
}
});

@ -43,9 +43,9 @@ public class CameraActivity extends AppCompatActivity implements View.OnClickLis
camera = findViewById(R.id.camera);
camera.setLifecycleOwner(this);
camera.addCameraListener(new CameraListener() {
public void onCameraOpened(CameraOptions options) { onOpened(options); }
public void onPictureTaken(PictureResult result) { onPicture(result); }
public void onVideoTaken(VideoResult result) { onVideo(result); }
public void onCameraOpened(@NonNull CameraOptions options) { onOpened(options); }
public void onPictureTaken(@NonNull PictureResult result) { onPicture(result); }
public void onVideoTaken(@NonNull VideoResult result) { onVideo(result); }
public void onCameraError(@NonNull CameraException exception) {
onError(exception);
}

Loading…
Cancel
Save