diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java index c1c8d6ad..f1c5c2dc 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/IntegrationTest.java @@ -3,6 +3,8 @@ package com.otaliastudios.cameraview; import android.graphics.Bitmap; import android.graphics.PointF; +import android.hardware.Camera; +import android.os.Build; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; @@ -364,6 +366,25 @@ public class IntegrationTest extends BaseTest { // This also ensures there are no crashes when attaching it to camera parameters. } + @Test + public void testSetPlaySounds() { + controller.mPlaySoundsTask.listen(); + boolean oldValue = camera.getPlaySounds(); + boolean newValue = !oldValue; + camera.setPlaySounds(newValue); + controller.mPlaySoundsTask.await(300); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(camera.getCameraId(), info); + if (info.canDisableShutterSound) { + assertEquals(newValue, camera.getPlaySounds()); + } + } else { + assertEquals(oldValue, camera.getPlaySounds()); + } + } + //endregion //region testSetVideoQuality diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java index f2347292..a9e16af4 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/MockCameraController.java @@ -129,4 +129,9 @@ public class MockCameraController extends CameraController { void setVideoMaxSize(long videoMaxSizeInBytes) { } + + @Override + void setPlaySounds(boolean playSounds) { + + } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java index e1fe1420..39d01df2 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera1.java @@ -1,5 +1,6 @@ package com.otaliastudios.cameraview; +import android.annotation.TargetApi; import android.graphics.ImageFormat; import android.graphics.PointF; import android.graphics.Rect; @@ -9,6 +10,7 @@ import android.hardware.Camera; import android.location.Location; import android.media.CamcorderProfile; import android.media.MediaRecorder; +import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.WorkerThread; @@ -178,6 +180,7 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera mergeLocation(params, null); mergeWhiteBalance(params, WhiteBalance.DEFAULT); mergeHdr(params, Hdr.DEFAULT); + mergePlaySound(mPlaySounds); params.setRecordingHint(mSessionType == SessionType.VIDEO); mCamera.setParameters(params); @@ -366,6 +369,23 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera return false; } + @TargetApi(17) + private boolean mergePlaySound(boolean oldPlaySound) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + Camera.CameraInfo info = new Camera.CameraInfo(); + Camera.getCameraInfo(mCameraId, info); + if (info.canDisableShutterSound) { + mCamera.enableShutterSound(mPlaySounds); + return true; + } + } + if (mPlaySounds) { + return true; + } + mPlaySounds = oldPlaySound; + return false; + } + @Override void setAudio(Audio audio) { @@ -572,15 +592,19 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera private boolean isCameraAvailable() { switch (mState) { // If we are stopped, don't. - case STATE_STOPPED: return false; + case STATE_STOPPED: + return false; // If we are going to be closed, don't act on camera. // Even if mCamera != null, it might have been released. - case STATE_STOPPING: return false; + case STATE_STOPPING: + return false; // If we are started, mCamera should never be null. - case STATE_STARTED: return true; + case STATE_STARTED: + return true; // If we are starting, theoretically we could act. // Just check that camera is available. - case STATE_STARTING: return mCamera != null; + case STATE_STARTING: + return mCamera != null; } return false; } @@ -678,15 +702,15 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera mMediaRecorder.setOrientationHint(computeSensorToOutputOffset()); //If the user sets a max file size, set it to the max file size - if(mVideoMaxSizeInBytes > 0) { + if (mVideoMaxSizeInBytes > 0) { mMediaRecorder.setMaxFileSize(mVideoMaxSizeInBytes); //Attach a listener to the media recorder to listen for file size notifications mMediaRecorder.setOnInfoListener(new MediaRecorder.OnInfoListener() { @Override public void onInfo(MediaRecorder mediaRecorder, int i, int i1) { - switch (i){ - case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED:{ + switch (i) { + case MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED: { endVideoImmediately(); break; } @@ -858,6 +882,18 @@ class Camera1 extends CameraController implements Camera.PreviewCallback, Camera mVideoMaxSizeInBytes = videoMaxSizeInBytes; } + @Override + void setPlaySounds(boolean playSounds) { + final boolean old = mPlaySounds; + mPlaySounds = playSounds; + schedule(mPlaySoundsTask, true, new Runnable() { + @Override + public void run() { + mergePlaySound(old); + } + }); + } + // ----------------- // Additional helper info } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java index 9c1346d2..9b827890 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/Camera2.java @@ -119,4 +119,9 @@ class Camera2 extends CameraController { void setVideoMaxSize(long videoMaxSizeInBytes) { } + + @Override + void setPlaySounds(boolean playSounds) { + + } } diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java index ba39b2f4..d98f9e96 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraController.java @@ -45,6 +45,7 @@ abstract class CameraController implements protected Audio mAudio; protected float mZoomValue; protected float mExposureCorrectionValue; + protected boolean mPlaySounds; protected int mCameraId; protected ExtraProperties mExtraProperties; @@ -77,6 +78,7 @@ abstract class CameraController implements Task mLocationTask = new Task<>(); Task mVideoQualityTask = new Task<>(); Task mStartVideoTask = new Task<>(); + Task mPlaySoundsTask = new Task<>(); CameraController(CameraView.CameraCallbacks callback) { mCameraCallbacks = callback; @@ -320,6 +322,8 @@ abstract class CameraController implements abstract void setVideoMaxSize(long videoMaxSizeInBytes); + abstract void setPlaySounds(boolean playSounds); + //endregion //region final getters diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 4b0a1dec..aaa5a23e 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -1361,6 +1361,7 @@ public class CameraView extends FrameLayout { */ public void setPlaySounds(boolean playSounds) { mPlaySounds = playSounds && Build.VERSION.SDK_INT >= 16; + mCameraController.setPlaySounds(playSounds); } /** @@ -1705,5 +1706,10 @@ public class CameraView extends FrameLayout { return mCameraController.getFlash(); } + + /* for tests */int getCameraId(){ + return mCameraController.mCameraId; + } + //endregion }