diff --git a/camera/MultiCameraApplication/AndroidManifest.xml b/camera/MultiCameraApplication/AndroidManifest.xml index 35633d5..6ee8cf1 100644 --- a/camera/MultiCameraApplication/AndroidManifest.xml +++ b/camera/MultiCameraApplication/AndroidManifest.xml @@ -19,11 +19,19 @@ android:supportsRtl="true" android:theme="@style/AppTheme" android:requestLegacyExternalStorage="true"> - - + + + @@ -35,9 +43,9 @@ "> + android:theme="@style/AppTheme.NoActionBar"> @@ -47,13 +55,8 @@ - - - - + android:name=".PermissionsActivity" + android:label="@string/app_name" /> diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/CameraBase.java b/camera/MultiCameraApplication/java/com/intel/multicamera/CameraBase.java index a9aa89e..d0d2b48 100644 --- a/camera/MultiCameraApplication/java/com/intel/multicamera/CameraBase.java +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/CameraBase.java @@ -26,6 +26,7 @@ import android.graphics.Bitmap; import android.graphics.ImageFormat; import android.graphics.Matrix; +import android.graphics.Picture; import android.graphics.RectF; import android.graphics.SurfaceTexture; import android.hardware.camera2.*; @@ -49,6 +50,7 @@ import android.view.Surface; import android.view.TextureView; import android.view.View; +import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.ImageView; @@ -62,8 +64,10 @@ import java.util.Arrays; import java.util.List; import java.util.Optional; +import java.util.concurrent.TimeUnit; -public class CameraBase implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener { + +public class CameraBase { private Activity mActivity; private String TAG; /** @@ -72,40 +76,30 @@ public class CameraBase implements MediaRecorder.OnErrorListener, MediaRecorder. private AutoFitTextureView textureView; private ImageButton FullScrn, SettingsView, takePictureButton, TakeVideoButton; - private MediaRecorder mMediaRecorder; private String cameraId; - private CameraDevice cameraDevice; + private CameraDevice mCameraDevice; private CameraCaptureSession cameraCaptureSessions; private CaptureRequest.Builder captureRequestBuilder; private Size previewSize; private ImageReader imageReader; private Handler mBackgroundHandler; private HandlerThread mBackgroundThread; - private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90; - private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270; - private static final SparseIntArray DEFAULT_ORIENTATIONS = new SparseIntArray(); - private static final SparseIntArray INVERSE_ORIENTATIONS = new SparseIntArray(); private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); private SharedPreferences settings; private SurfaceTexture mSurfaceTexture; private String Capture_Key, Video_key, SettingsKey; - private long mRecordingStartTime; - private boolean mRecordingTimeCountsDown = false; - private static final int MSG_UPDATE_RECORD_TIME = 5; + + private CameraBase mCameraBase; private static final String SIZE_HD = "HD 720p"; /** * Whether the app is recording video now */ private boolean mIsRecordingVideo; + private MultiCamera ic_camera; - // The video file that the hardware camera is about to record into - // (or is recording into. - private String mVideoFilename; - private ContentValues mCurrentFileInfo, mCurrentVideoValues; - private final Handler mHandler; - private TextView mRecordingTimeView; - + private PhotoPreview mPhoto; + private VideoRecord mRecord; /** * Orientation of the camera sensor */ @@ -124,7 +118,6 @@ public class CameraBase implements MediaRecorder.OnErrorListener, MediaRecorder. private RoundedThumbnailView mRoundedThumbnailView; FrameLayout roundedThumbnailViewControlLayout; - private Uri mCurrentUri; private String[] ImageFileDetails; public CameraBase(Activity activity, AutoFitTextureView mtextureView, ImageButton[] Button, @@ -132,239 +125,135 @@ public CameraBase(Activity activity, AutoFitTextureView mtextureView, ImageButto RoundedThumbnailView roundedThumbnailView) { this.mActivity = activity; this.textureView = mtextureView; - this.ClickListeners(Button[0], Button[1]); - SettingsView = Button[2]; - FullScrn = Button[3]; + if (Button != null) { + this.ClickListeners(Button[0], Button[1], Button[2], Button[4], Button[5]); + SettingsView = Button[2]; + FullScrn = Button[3]; + } this.settings = PreferenceManager.getDefaultSharedPreferences(activity); cameraId = data[1]; TAG = data[0]; Capture_Key = data[2]; Video_key = data[3]; SettingsKey = data[4]; - mHandler = new MainHandler(); - - mRecordingTimeView = RecordingTimeView; - mRoundedThumbnailView = roundedThumbnailView; + ic_camera = MultiCamera.getInstance(); - RoundedThumbnail_setOnClickListners(); + mPhoto = new PhotoPreview(activity, roundedThumbnailView, cameraId); + mRecord = new VideoRecord(this, Video_key,cameraId, mtextureView, mActivity, + RecordingTimeView, SettingsKey); roundedThumbnailViewControlLayout = mActivity.findViewById(R.id.control1); - - Log.v(TAG, "constructor called"); + mCameraBase = this; } - private void RoundedThumbnail_setOnClickListners() { - mRoundedThumbnailView.setCallback(new RoundedThumbnailView.Callback() { - @Override - public void onHitStateFinished() { - ImageView preView; - final ImageButton btnDelete, playButton, btnBack, details; - FrameLayout previewLayout; - - String mimeType = Utils.getMimeTypeFromURI(mActivity, mCurrentUri); - - previewLayout = mActivity.findViewById(R.id.previewLayout); - previewLayout.setVisibility(View.VISIBLE); - - btnDelete = mActivity.findViewById(R.id.control_delete); - playButton = mActivity.findViewById(R.id.play_button); - preView = mActivity.findViewById(R.id.preview); - btnBack = mActivity.findViewById(R.id.control_back); - details = mActivity.findViewById(R.id.control_info); - details.setVisibility(View.VISIBLE); - - btnBack.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - FrameLayout previewLayout; - previewLayout = mActivity.findViewById(R.id.previewLayout); - previewLayout.setVisibility(View.GONE); - - mRoundedThumbnailView.hideThumbnail(); - } - }); - - btnDelete.setOnClickListener(new View.OnClickListener() { - ImageView preView; + private void ClickListeners(ImageButton PictureButton, ImageButton RecordButton, + ImageButton Settings, ImageButton CameraSwitch, ImageButton CameraSplit) { + TakePicureOnClicked(PictureButton); - @Override - public void onClick(View v) { - preView = mActivity.findViewById(R.id.preview); - - Uri uri = mCurrentUri; - File file = new File(Utils.getRealPathFromURI(mActivity, uri)); - if (file.exists()) { - Log.v(TAG, " Thumbnail Preview File Deleted "); - file.delete(); - // request scan - Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); - scanIntent.setData(Uri.fromFile(file)); - mActivity.sendBroadcast(scanIntent); - preView.setImageResource(android.R.color.background_dark); - details.setVisibility(View.INVISIBLE); - } - } - }); + StartVideoRecording(RecordButton, PictureButton, CameraSwitch, CameraSplit, Settings); + CameraSplit(CameraSplit); + } - details.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - showDetailsDialog(mCurrentFileInfo); - } - }); - if (mimeType.compareTo("video/mp4") == 0) { - VideoPreview(playButton, preView); + private void TakePicureOnClicked(ImageButton PictureButton) { + takePictureButton = PictureButton; + if (takePictureButton == null) return; - } else { - photoPreview(playButton, preView); + takePictureButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (ic_camera.getTopRightCam() != null && + ic_camera.getTopRightCam() == mCameraBase) { + ic_camera.setOpenCameraId(1); } - } - }); - } - - private void VideoPreview(ImageButton playButton, ImageView preView) { - final Optional bitmap = - Utils.getVideoThumbnail(mActivity.getContentResolver(), mCurrentUri); - if (bitmap.isPresent()) { - playButton.setVisibility(View.VISIBLE); - - playButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Utils.playVideo(mActivity, mCurrentUri, TAG); + if (ic_camera.getBotLeftCam() != null && ic_camera.getBotLeftCam() == mCameraBase) { + ic_camera.setOpenCameraId(2); } - }); - - preView.setVisibility(View.VISIBLE); - preView.setImageBitmap(bitmap.get()); - - } else { - Log.e(TAG, "No bitmap image found: "); - } - } - - private void photoPreview(ImageButton playButton, ImageView preView) { - Uri PhotoUri = mCurrentUri; - - preView.setVisibility(View.VISIBLE); - playButton.setVisibility(View.GONE); - preView.setImageURI(PhotoUri); - } - - /** - * This Handler is used to post message back onto the main thread of the - * application. - */ - private class MainHandler extends Handler { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MSG_UPDATE_RECORD_TIME: { - updateRecordingTime(); - break; + if (ic_camera.getTopLeftCam() != null && ic_camera.getTopLeftCam() == mCameraBase) { + ic_camera.setOpenCameraId(0); } + if (ic_camera.getBotRightCam() != null && + ic_camera.getBotRightCam() == mCameraBase) { + ic_camera.setOpenCameraId(3); + } + System.out.println(TAG + "take pic start camera id"+ic_camera.getOpenCameraId()); - default: - Log.v(TAG, "Unhandled message: " + msg.what); - break; - } - } - } - - private void updateRecordingTime() { - if (!mIsRecordingVideo) { - return; - } - long now = SystemClock.uptimeMillis(); - long delta = now - mRecordingStartTime; - long mMaxVideoDurationInMs; - mMaxVideoDurationInMs = Utils.getMaxVideoDuration(mActivity); - - // Starting a minute before reaching the max duration - // limit, we'll countdown the remaining time instead. - boolean countdownRemainingTime = - (mMaxVideoDurationInMs != 0 && delta >= mMaxVideoDurationInMs - 60000); - - long deltaAdjusted = delta; - if (countdownRemainingTime) { - deltaAdjusted = Math.max(0, mMaxVideoDurationInMs - deltaAdjusted) + 999; - } - String text; - - long targetNextUpdateDelay; - - text = Utils.millisecondToTimeString(deltaAdjusted, false); - targetNextUpdateDelay = 1000; - - setRecordingTime(text); - - if (mRecordingTimeCountsDown != countdownRemainingTime) { - // Avoid setting the color on every update, do it only - // when it needs changing. - mRecordingTimeCountsDown = countdownRemainingTime; - - int color = mActivity.getResources().getColor(R.color.recording_time_remaining_text); - - setRecordingTimeTextColor(color); - } - - long actualNextUpdateDelay = targetNextUpdateDelay - (delta % targetNextUpdateDelay); - mHandler.sendEmptyMessageDelayed(MSG_UPDATE_RECORD_TIME, actualNextUpdateDelay); - } - - private void setRecordingTime(String text) { - mRecordingTimeView.setText(text); - } - - private void setRecordingTimeTextColor(int color) { - mRecordingTimeView.setTextColor(color); - } - - private void showRecordingUI(boolean recording) { - if (recording) { - mRecordingTimeView.setText(""); - mRecordingTimeView.setVisibility(View.VISIBLE); - mRecordingTimeView.announceForAccessibility( - mActivity.getResources().getString(R.string.video_recording_started)); + MultiViewActivity Mactivity = (MultiViewActivity) mActivity; + Mactivity.closeCamera(); + ic_camera.setIsCameraOrSurveillance(0); + Intent intent = new Intent(mActivity, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + mActivity.startActivity(intent); + mActivity.finish(); - } else { - mRecordingTimeView.announceForAccessibility( - mActivity.getResources().getString(R.string.video_recording_stopped)); - mRecordingTimeView.setVisibility(View.GONE); - } + } + }); } - private void ClickListeners(ImageButton PictureButton, ImageButton RecordButton) { - TakePicureOnClicked(PictureButton); - - StartVideoRecording(RecordButton); - } + private void CameraSplit(ImageButton cameraSplit) { + if (cameraSplit == null) return; - private void TakePicureOnClicked(ImageButton PictureButton) { - takePictureButton = PictureButton; - if (takePictureButton == null) return; - - takePictureButton.setOnClickListener(new View.OnClickListener() { + cameraSplit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - takePicture(); + Toast.makeText(mActivity, "camera split clicked ", Toast.LENGTH_LONG).show(); + System.out.println("camera split"); + MultiCamera ic_camera = MultiCamera.getInstance(); + MultiViewActivity Mactivity = (MultiViewActivity) mActivity; + if (ic_camera.getIsCameraOrSurveillance() == 0) { + ic_camera.setIsCameraOrSurveillance(1); + Intent intent = new Intent(mActivity, MultiViewActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + mActivity.startActivity(intent); + mActivity.finish(); + } else { + System.out.println("camera split calling single camera activity"); + ic_camera.setIsCameraOrSurveillance(1); + Intent intent = new Intent(mActivity, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + mActivity.startActivity(intent); + mActivity.finish(); + } } }); } - private void StartVideoRecording(ImageButton RecordButton) { + private void StartVideoRecording(ImageButton RecordButton, final ImageButton Capture, + ImageButton Switch, final ImageButton Split, final ImageButton Settings) { TakeVideoButton = RecordButton; TakeVideoButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (mIsRecordingVideo) { - stopRecordingVideo(); - - } else { - startRecordingVideo(); + try { + MultiViewActivity MultiActivity = (MultiViewActivity) mActivity; + + if (mIsRecordingVideo) { + mIsRecordingVideo = false; + + mRecord.stopRecordingVideo(); + mRecord.showRecordingUI(false); + mPhoto.showVideoThumbnail(); + + MultiActivity.enterFullScreen(view); + Capture.setVisibility(View.VISIBLE); + TakeVideoButton.setImageResource(R.drawable.ic_capture_video); + Split.setVisibility(View.VISIBLE); + Settings.setVisibility(View.VISIBLE); + } else { + + mIsRecordingVideo =true; + mRecord.startRecordingVideo(); + mRecord.showRecordingUI(true); + MultiActivity.enterFullScreen(view); + Settings.setVisibility(View.GONE); + Capture.setVisibility(View.GONE); + TakeVideoButton.setImageResource(R.drawable.ic_stop_normal); + Split.setVisibility(View.GONE); + } + } catch (Exception e) { + Log.e(TAG, "Recording failed"); } } }); @@ -375,6 +264,11 @@ public void onClick(View view) { public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { // open your camera here mSurfaceTexture = surface; + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (Exception e) { + + } openCamera(width, height); } @@ -413,8 +307,6 @@ private void openCamera(int width, int height) { mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); - startBackgroundThread(); - manager.openCamera(cameraId, stateCallback, null); } catch (CameraAccessException e) { @@ -427,8 +319,9 @@ private void openCamera(int width, int height) { public void onOpened(CameraDevice camera) { // This is called when the camera is open Log.i(TAG, "Camera opened successfully with id " + camera.getId()); - cameraDevice = camera; - UI_Enable(true); + mCameraDevice = camera; + mRecord.setCameraDevice(mCameraDevice); + createCameraPreview(); MultiViewActivity.updateStorageSpace(null); } @@ -436,23 +329,26 @@ public void onOpened(CameraDevice camera) { @Override public void onDisconnected(CameraDevice camera) { Log.v(TAG, "onDisconnected"); + mCameraDevice = camera; closeCamera(); } @Override public void onError(CameraDevice camera, int error) { Log.v(TAG, "onError"); + mCameraDevice = camera; closeCamera(); } @Override public void onClosed(@NonNull CameraDevice camera) { Log.v(TAG, "onClose"); + mCameraDevice = camera; super.onClosed(camera); previewSize = SIZE_720P; configureTransform(textureView.getWidth(), textureView.getHeight()); SurfaceUtil.clear(mSurfaceTexture); - UI_Enable(false); + ResetResolutionSettings(); } }; @@ -464,28 +360,6 @@ private void ResetResolutionSettings() { edit.apply(); } - private void UI_Enable(boolean flag) { - TakeVideoButton.setEnabled(flag); - - takePictureButton.setEnabled(flag); - - SettingsView.setEnabled(flag); - - FullScrn.setEnabled(flag); - - if (flag) { - TakeVideoButton.setImageResource(R.drawable.ic_capture_video); - takePictureButton.setImageResource(R.drawable.ic_capture_camera_normal); - SettingsView.setImageAlpha(200); - FullScrn.setImageAlpha(200); - } else { - TakeVideoButton.setImageResource(R.drawable.ic_capture_video_disabled); - takePictureButton.setImageResource(R.drawable.ic_capture_camera_disabled); - SettingsView.setImageAlpha(95); - FullScrn.setImageAlpha(95); - } - } - private void configureTransform(int viewWidth, int viewHeight) { if (null == textureView || null == previewSize) { return; @@ -579,7 +453,7 @@ private Size getSelectedDimension(String Key) { public void createCameraPreview() { try { - closePreviewSession(); + mRecord.closePreviewSession(); SurfaceTexture texture = textureView.getSurfaceTexture(); if (texture == null) return; @@ -608,16 +482,16 @@ public void createCameraPreview() { adjustAspectRatio(previewSize.getWidth(), previewSize.getHeight()); captureRequestBuilder = - cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); captureRequestBuilder.addTarget(surface); - cameraDevice.createCaptureSession( + mCameraDevice.createCaptureSession( Arrays.asList(surface), new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession cameraCaptureSession) { // The camera is already closed - if (null == cameraDevice) { + if (null == mCameraDevice) { return; } // When the session is ready, we start displaying the preview. @@ -639,45 +513,35 @@ public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { } public void closeCamera() { - if (mIsRecordingVideo) { - stopRecordingVideo(); - } + try { + if (mIsRecordingVideo) { + mRecord.stopRecordingVideo(); + } + mRecord.closePreviewSession(); + try { + new Thread(new Runnable() { + @Override + public void run() { + if (null != mCameraDevice) { + //mCameraDevice.wait(200); + mCameraDevice.close(); + mCameraDevice = null; + } + } + }).start(); + } catch (Exception e) { + System.out.println(TAG +" camera close exception"); + } - closePreviewSession(); - if (null != cameraDevice) { - cameraDevice.close(); - cameraDevice = null; - } - if (null != imageReader) { - imageReader.close(); - imageReader = null; - } - releaseMedia(); - stopBackgroundThread(); - } + if (null != imageReader) { + imageReader.close(); + imageReader = null; + } - /** - * Starts a background thread and its {@link Handler}. - */ - private void startBackgroundThread() { - mBackgroundThread = new HandlerThread(TAG); - mBackgroundThread.start(); - mBackgroundHandler = new Handler(mBackgroundThread.getLooper()); - } + mRecord.releaseMedia(); - /** - * Stops the background thread and its {@link Handler}. - */ - private void stopBackgroundThread() { - if (mBackgroundThread != null) { - mBackgroundThread.quitSafely(); - try { - mBackgroundThread.join(); - mBackgroundThread = null; - mBackgroundHandler = null; - } catch (InterruptedException e) { - e.printStackTrace(); - } + } catch (Exception e) { + System.out.println("close camera exception "); } } @@ -727,7 +591,7 @@ private void adjustAspectRatio(int videoWidth, int videoHeight) { } private void updatePreview() { - if (null == cameraDevice) { + if (null == mCameraDevice) { Log.e(TAG, "updatePreview error"); } captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); @@ -755,8 +619,8 @@ private int getOrientation(int rotation) { return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360; } - private void takePicture() { - if (null == cameraDevice) { + public void takePicture() { + if (null == mCameraDevice) { Log.e(TAG, "cameraDevice is null"); return; } @@ -778,7 +642,7 @@ private void takePicture() { outputSurfaces.add(reader.getSurface()); captureRequestBuilder = - cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); + mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE); captureRequestBuilder.addTarget(reader.getSurface()); captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); @@ -842,12 +706,12 @@ public void onCaptureCompleted(CameraCaptureSession session, saveImage(imageDimension, ImageFile); - showImageThumbnail(ImageFile); + mPhoto.showImageThumbnail(ImageFile); createCameraPreview(); } }; - cameraDevice.createCaptureSession( + mCameraDevice.createCaptureSession( outputSurfaces, new CameraCaptureSession.StateCallback() { @Override public void onConfigured(CameraCaptureSession session) { @@ -878,378 +742,11 @@ private void saveImage(Size imageDimension, File ImageFile) { uri = Utils.broadcastNewPicture(mActivity.getApplicationContext(), mCurrentPictureValues); - mCurrentUri = uri; - - mCurrentFileInfo = mCurrentPictureValues; - Log.i(TAG, "Image saved @ " + ImageFile.getAbsolutePath()); - } - - private void showImageThumbnail(File ImageFile) { - final int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); - final Optional bitmap = - Utils.generateThumbnail(ImageFile, roundedThumbnailViewControlLayout.getWidth(), - roundedThumbnailViewControlLayout.getMeasuredHeight()); - - if (bitmap.isPresent()) { - mActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - mRoundedThumbnailView.startRevealThumbnailAnimation("photo taken"); - mRoundedThumbnailView.setThumbnail(bitmap.get(), getOrientation(rotation)); - } - }); - - } else { - Log.e(TAG, "No bitmap image found: "); - } - } - - /* Recording Start*/ - private void startRecordingVideo() { - if (null == cameraDevice || !textureView.isAvailable()) { - return; - } - MultiViewActivity.updateStorageSpace(new MultiViewActivity.OnStorageUpdateDoneListener() { - @Override - public void onStorageUpdateDone(long bytes) throws IOException, CameraAccessException { - if (bytes <= Utils.LOW_STORAGE_THRESHOLD_BYTES) { - Log.w(TAG, "Storage issue, ignore the start request"); - Toast.makeText(mActivity, "LOW_STORAGE", Toast.LENGTH_SHORT).show(); - } else { - CamcorderProfile mProfile; - mProfile = getSelectedCamorderProfile(); - setUpMediaRecorder(mProfile); - startRecorder(mProfile); - } - } - }); - } - - private CamcorderProfile getSelectedCamorderProfile() { - CamcorderProfile mProfile; - - settings = PreferenceManager.getDefaultSharedPreferences(mActivity); - String videoQuality = settings.getString(Video_key, SIZE_HD); - - int quality = SettingsPrefUtil.getFromSetting(videoQuality); - - Log.i(TAG, "Selected video quality " + videoQuality); - - mProfile = CamcorderProfile.get(0, quality); - - return mProfile; - } - - private void startRecorder(CamcorderProfile mProfile) - throws IOException, CameraAccessException { - closePreviewSession(); - - SurfaceTexture texture = textureView.getSurfaceTexture(); - if (texture == null) return; - - if (mProfile.videoFrameWidth == 1280 || mProfile.videoFrameHeight == 1920) { - previewSize = SIZE_720P; - - } else if (mProfile.videoFrameWidth == 640 || mProfile.videoFrameHeight == 320) { - previewSize = SIZE_480P; - } - - Log.i(TAG, - "Video previewSize " + previewSize.getWidth() + " x " + previewSize.getHeight()); - - texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); - - adjustAspectRatio(previewSize.getWidth(), previewSize.getHeight()); - - captureRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); - List surfaces = new ArrayList<>(); - - // Set up Surface for the camera preview - Surface previewSurface = new Surface(texture); - surfaces.add(previewSurface); - captureRequestBuilder.addTarget(previewSurface); - - // Set up Surface for the MediaRecorder - Surface recorderSurface = mMediaRecorder.getSurface(); - surfaces.add(recorderSurface); - captureRequestBuilder.addTarget(recorderSurface); - - // Start a capture session - // Once the session starts, we can update the UI and start recording - cameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { - @Override - public void onConfigured(@NonNull CameraCaptureSession camCaptureSession) { - cameraCaptureSessions = camCaptureSession; - updatePreview(); - mActivity.runOnUiThread(new Runnable() { - @Override - public void run() { - // UI - mIsRecordingVideo = true; - - // Start recording - - mMediaRecorder.start(); - Log.i(TAG, "MediaRecorder recording.... "); - - mRecordingStartTime = SystemClock.uptimeMillis(); - - VideoUI(mIsRecordingVideo); - - updateRecordingTime(); - } - }); - } - - @Override - public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { - if (null != mActivity) { - Log.e(TAG, "Recording Failed"); - Toast.makeText(mActivity, "Recording Failed", Toast.LENGTH_SHORT).show(); - } - - releaseMedia(); - } - }, mBackgroundHandler); - } - - private void setUpMediaRecorder(CamcorderProfile mProfile) throws IOException { - if (null == mActivity) { - return; - } - String[] VideofileDetails; - - mMediaRecorder = new MediaRecorder(); - mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); - mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); - - { - Context mContext = mActivity.getApplicationContext(); - AudioManager mAudioManager = - (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); - AudioDeviceInfo[] deviceList = - mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS); - for (AudioDeviceInfo audioDeviceInfo : deviceList) { - if (audioDeviceInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) { - mMediaRecorder.setPreferredDevice(audioDeviceInfo); - break; - } - } - } - - VideofileDetails = Utils.generateFileDetails(Utils.MEDIA_TYPE_VIDEO); - if (VideofileDetails == null || VideofileDetails.length < 5) { - Log.e(TAG, "setUpMediaRecorder Invalid file details"); - return; - } - - mCurrentVideoValues = - Utils.getContentValues(Utils.MEDIA_TYPE_VIDEO, VideofileDetails, - mProfile.videoFrameWidth, mProfile.videoFrameHeight, 0, 0); - - mVideoFilename = VideofileDetails[3]; - - mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); - /** - * set output file in media recorder - */ - mMediaRecorder.setOutputFile(mVideoFilename); - - mMediaRecorder.setVideoEncodingBitRate(10000000); - mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); - - Log.i(TAG, "MediaRecorder VideoSize " + mProfile.videoFrameWidth + " x " + - mProfile.videoFrameHeight); - - mMediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight); - mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); - mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); - - int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); - - switch (mSensorOrientation) { - case SENSOR_ORIENTATION_DEFAULT_DEGREES: - mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation)); - break; - case SENSOR_ORIENTATION_INVERSE_DEGREES: - mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation)); - break; - } - - // Set maximum file size. - long maxFileSize = - MultiViewActivity.getStorageSpaceBytes() - Utils.LOW_STORAGE_THRESHOLD_BYTES; - Log.d(TAG, "maximum file size is" + maxFileSize); - Toast.makeText(mActivity, "maxFileSize is " + maxFileSize, Toast.LENGTH_SHORT).show(); - try { - mMediaRecorder.setMaxFileSize(maxFileSize); - } catch (RuntimeException exception) { - // We are going to ignore failure of setMaxFileSize here, as - // a) The composer selected may simply not support it, or - // b) The underlying media framework may not handle 64-bit range - // on the size restriction. - } - - try { - mMediaRecorder.prepare(); - } catch (IOException ex) { - Log.e(TAG, "MediaRecorder prepare failed for " + mVideoFilename, ex); - releaseMedia(); - throw new RuntimeException(ex); - } - - mMediaRecorder.setOnErrorListener(this); - mMediaRecorder.setOnInfoListener(this); - } - - // from MediaRecorder.OnErrorListener - @Override - public void onError(MediaRecorder mr, int what, int extra) { - Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra); - if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { - // We may have run out of space on the sdcard. - stopRecordingVideo(); - MultiViewActivity.updateStorageSpace(null); - } - } - - // from MediaRecorder.OnInfoListener - @Override - public void onInfo(MediaRecorder mr, int what, int extra) { - String[] VideofileDetails = new String[0]; - if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING) { - Toast.makeText(mActivity, R.string.video_reach_size_limit, Toast.LENGTH_SHORT).show(); - - if (mIsRecordingVideo) { - saveVideo(); - - VideofileDetails = Utils.generateFileDetails(Utils.MEDIA_TYPE_VIDEO); - if (VideofileDetails == null || VideofileDetails.length < 5) { - Log.e(TAG, "setUpMediaRecorder Invalid file details"); - return; - } - - mVideoFilename = VideofileDetails[3]; - - CamcorderProfile mProfile = getSelectedCamorderProfile(); - - mCurrentVideoValues = Utils.getContentValues( - Utils.MEDIA_TYPE_VIDEO, VideofileDetails, mProfile.videoFrameWidth, - mProfile.videoFrameHeight, 0, 0); - - try { - mMediaRecorder.setNextOutputFile(new File(VideofileDetails[3])); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - MultiViewActivity.updateStorageSpace(null); - } - - private void closePreviewSession() { - if (cameraCaptureSessions != null) { - cameraCaptureSessions.close(); - cameraCaptureSessions = null; - } - } + ic_camera.setCurrentUri(uri); - private void releaseMedia() { - if (null != mMediaRecorder) { - try { - mMediaRecorder.setOnErrorListener(null); - mMediaRecorder.setOnInfoListener(null); - mMediaRecorder.stop(); - Log.i(TAG, "MediaRecorder stop "); - - } catch (IllegalStateException e) { - Log.e(TAG, "stop fail", e); - if (mVideoFilename != null) { - deleteVideoFile(mVideoFilename); - } - } - mMediaRecorder.reset(); - mMediaRecorder.release(); - mMediaRecorder = null; - } - } - - private void deleteVideoFile(String fileName) { - Log.v(TAG, "Deleting video " + fileName); - File f = new File(fileName); - if (!f.delete()) { - Log.e(TAG, "Could not delete " + fileName); - } - } + ic_camera.setCurrentFileInfo(mCurrentPictureValues); - private void saveVideo() { - long duration = SystemClock.uptimeMillis() - mRecordingStartTime; - if (duration > 0) { - // - } else { - Log.w(TAG, "Video duration <= 0 : " + duration); - } - Uri uri; - - mCurrentVideoValues.put(MediaStore.Video.Media.DURATION, duration); - mCurrentVideoValues.put(MediaStore.Video.Media.SIZE, new File(mVideoFilename).length()); - - uri = Utils.broadcastNewVideo(mActivity.getApplicationContext(), mCurrentVideoValues); - - mCurrentUri = uri; - - mCurrentFileInfo = mCurrentVideoValues; - - Log.i(TAG, "video saved @: " + mVideoFilename); - - mVideoFilename = null; - } - - private void showVideoThumbnail() { - mRoundedThumbnailView.startRevealThumbnailAnimation("Video taken"); - - final Optional bitmap = - Utils.getVideoThumbnail(mActivity.getContentResolver(), mCurrentUri); - - if (bitmap.isPresent()) { - mRoundedThumbnailView.setThumbnail(bitmap.get(), 0); - } else { - Log.e(TAG, "No bitmap image found: "); - } - } - - private void VideoUI(boolean toggle) { - if (toggle) { - mRoundedThumbnailView.setVisibility(View.GONE); - takePictureButton.setVisibility(View.GONE); - SettingsView.setEnabled(false); - SettingsView.setImageAlpha(95); - showRecordingUI(mIsRecordingVideo); - TakeVideoButton.setImageResource(R.drawable.ic_stop_normal); - - } else { - showRecordingUI(mIsRecordingVideo); - TakeVideoButton.setImageResource(R.drawable.ic_capture_video); - takePictureButton.setVisibility(View.VISIBLE); - SettingsView.setEnabled(true); - SettingsView.setImageAlpha(200); - } - } - - private void stopRecordingVideo() { - mHandler.removeMessages(MSG_UPDATE_RECORD_TIME); - mIsRecordingVideo = false; - - releaseMedia(); - - saveVideo(); - - showVideoThumbnail(); - - createCameraPreview(); - - VideoUI(mIsRecordingVideo); + Log.i(TAG, "Image saved @ " + ImageFile.getAbsolutePath()); } private void showDetailsDialog(ContentValues info) { @@ -1260,4 +757,13 @@ private void showDetailsDialog(ContentValues info) { Dialog detailDialog = DetailsDialog.create(mActivity, details.get()); detailDialog.show(); } + + public PhotoPreview getmPhoto() { + return mPhoto; + } + + public VideoRecord getmRecord() { + return mRecord; + } + } diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/FullScreenActivity.java b/camera/MultiCameraApplication/java/com/intel/multicamera/FullScreenActivity.java new file mode 100644 index 0000000..20a7b06 --- /dev/null +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/FullScreenActivity.java @@ -0,0 +1,449 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2019 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.multicamera; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; + +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraManager; +import android.hardware.usb.UsbManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import java.io.File; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import static com.intel.multicamera.MultiViewActivity.updateStorageSpace; + +public class FullScreenActivity extends AppCompatActivity { + private static final String TAG = "FullScreenActivity"; + private boolean mHasCriticalPermissions; + + public String[] CameraIds; + private int numOfCameras; + private AutoFitTextureView mCamera_BackView, mCamera_FrontView; + + private ImageButton mCameraSwitch, mCameraPicture, mCameraRecord, mCameraSplit, mSettings; + private ImageButton mSettingClose; + + private SettingsPrefUtil Fragment; + private long mLastClickTime = 0; + MultiCamera mCameraInst; + private TextView mRecordingTimeView; + private boolean mIsRecordingVideo; + private CameraBase mCameraBack; + private CameraBase mCameraFront; + private RoundedThumbnailView mRoundedThumbnailView; + private BroadcastReceiver mUsbReceiver; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setHomeButtonEnabled(true); + } + + setContentView(R.layout.activity_full_screen); + + mIsRecordingVideo = false; + mCameraInst = MultiCamera.getInstance(); + mCameraSwitch = findViewById(R.id.camera_switch); + mCameraPicture = findViewById(R.id.Picture); + mCameraRecord = findViewById(R.id.Record); + mCameraSplit = findViewById(R.id.camera_split_view); + mRecordingTimeView = findViewById(R.id.recording_time); + mSettings = findViewById(R.id.SettingView); + mSettingClose = findViewById(R.id.SettingClose); + mRoundedThumbnailView = findViewById(R.id.rounded_thumbnail_view); + + checkPermissions(); + + openBackCamera(); + + IntentFilter filter = new IntentFilter(); + filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + + // BroadcastReceiver when insert/remove the device USB plug into/from a USB port + mUsbReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + System.out.println("BroadcastReceiver Event"); + if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) { + System.out.println(TAG+"BroadcastReceiver USB Connected"); + openBackCamera(); + + } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { + System.out.println(TAG+"BroadcastReceiver USB Disconnected"); + openBackCamera(); + } + } + }; + + registerReceiver(mUsbReceiver , filter); + + mCameraSwitch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + MultiCamera ic_camera = MultiCamera.getInstance(); + if (ic_camera.getWhichCamera() == 0) { + openFrontCamera(); + ic_camera.setWhichCamera(1); + Log.i(TAG,"Opened front camera"); + } + else { + openBackCamera(); + ic_camera.setWhichCamera(0); + Log.i(TAG,"Opened back camera"); + } + + } + }); + + mSettings.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + Bundle bundle; + mSettingClose.setVisibility(View.VISIBLE); + + bundle = new Bundle(); + bundle.putString("Camera_id", CameraIds[0]); + bundle.putInt("root_preferences", R.xml.root_preferences); + bundle.putString("pref_resolution", "pref_resolution"); + bundle.putString("video_list", "video_list"); + bundle.putString("capture_list", "capture_list"); + + Fragment = new SettingsPrefUtil(); + Fragment.setArguments(bundle); + + getFragmentManager() + .beginTransaction() + .replace(R.id.PrefScrnSettings, Fragment) + .commit(); + + mSettings.setVisibility(View.GONE); + mSettingClose.setVisibility(View.VISIBLE); + mCameraRecord.setVisibility(View.GONE); + mCameraPicture.setVisibility(View.GONE); + mCameraSwitch.setVisibility(View.GONE); + mCameraSplit.setVisibility(View.GONE); + } + }); + + mSettingClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + getFragmentManager().beginTransaction().remove(Fragment).commit(); + + v.setVisibility(v.GONE); + mSettings.setVisibility(View.VISIBLE); + + mCameraRecord.setVisibility(View.VISIBLE); + mCameraPicture.setVisibility(View.VISIBLE); + mCameraSwitch.setVisibility(View.VISIBLE); + mCameraSplit.setVisibility(View.VISIBLE); + } + }); + + mCameraSplit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MultiCamera ic_camera = MultiCamera.getInstance(); + ic_camera.setIsCameraOrSurveillance(1); + Intent intent = new Intent(FullScreenActivity.this, MultiViewActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + }); + + mCameraPicture.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + if (MultiCamera.getInstance().getWhichCamera() == 1) { + if (mCameraFront != null) + mCameraFront.takePicture(); + } + else { + if (mCameraBack != null) + mCameraBack.takePicture(); + } + } + }); + + mCameraRecord.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + try { + if (mIsRecordingVideo) { + mIsRecordingVideo = false; + if (mCameraInst.getWhichCamera() == 0) { + mCameraBack.getmRecord().stopRecordingVideo(); + mCameraBack.getmRecord().showRecordingUI(false); + mCameraBack.getmPhoto().showVideoThumbnail(); + } + else { + mCameraFront.getmRecord().stopRecordingVideo(); + mCameraFront.getmRecord().showRecordingUI(false); + mCameraFront.getmPhoto().showVideoThumbnail(); + } + + mCameraSwitch.setVisibility(View.VISIBLE); + mCameraPicture.setVisibility(View.VISIBLE); + mCameraRecord.setImageResource(R.drawable.ic_capture_video); + mCameraSplit.setVisibility(View.VISIBLE); + mSettings.setVisibility(View.VISIBLE); + } else { + mIsRecordingVideo =true; + if (mCameraInst.getWhichCamera() == 0) { + mCameraBack.getmRecord().startRecordingVideo(); + } + else { + mCameraFront.getmRecord().startRecordingVideo(); + } + mCameraBack.getmRecord().showRecordingUI(true); + mSettings.setVisibility(View.GONE); + mCameraSwitch.setVisibility(View.GONE); + mCameraPicture.setVisibility(View.GONE); + mCameraRecord.setImageResource(R.drawable.ic_stop_normal); + mCameraSplit.setVisibility(View.GONE); + } + } catch (Exception e) { + System.out.println(TAG + "exception during record"); + } + } + }); + } + + public void openBackCamera() { + closeCamera(); + + GetCameraCnt(); + if (numOfCameras == 0) { + Toast.makeText(FullScreenActivity.this, "No Camera Found", Toast.LENGTH_LONG).show(); + System.out.println(TAG+" no camera found"); + return; + } + if (numOfCameras == 1) { + findViewById(R.id.camera_switch).setVisibility(View.GONE); + findViewById(R.id.camera_split_view).setVisibility(View.GONE); + } + + updateStorageSpace(null); + + OpenOnlyBackCamera(); + } + + public void openFrontCamera() { + closeCamera(); + + GetCameraCnt(); + updateStorageSpace(null); + + OpenOnlyFrontCamera(); + } + + private void OpenOnlyFrontCamera() { + + mCamera_FrontView = findViewById(R.id.textureview); + if (mCamera_FrontView == null) { + Log.e(TAG, "fail to get surface for front view"); + return; + } + if (mCameraFront == null) { + Open_FrontCamera(); + } + + if (mCamera_FrontView.isAvailable()) { + mCameraFront.textureListener.onSurfaceTextureAvailable( + mCamera_FrontView.getSurfaceTexture(), + mCamera_FrontView.getWidth(), mCamera_FrontView.getHeight()); + } else { + mCamera_FrontView.setSurfaceTextureListener(mCameraFront.textureListener); + } + } + private void closeCamera() { + + if (null != mCameraBack) { + mCameraBack.closeCamera(); + mCameraBack = null; + } + + if (null != mCameraFront) { + mCameraFront.closeCamera(); + mCameraFront = null; + } + } + + + public void GetCameraCnt() { + CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE); + + try { + CameraIds = manager.getCameraIdList(); + numOfCameras = manager.getCameraIdList().length; + if (numOfCameras == 0) { + Toast.makeText(FullScreenActivity.this, "No camera found closing the application", + Toast.LENGTH_LONG).show(); + } + Log.d(TAG, "Get total number of cameras present: " + manager.getCameraIdList().length); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void OpenOnlyBackCamera() { + mCamera_BackView = findViewById(R.id.textureview); + if (mCamera_BackView == null) { + Log.e(TAG, "fail to find surface for back camera"); + return; + } + if (mCameraBack == null) { + Open_BackCamera(); + } + if (mCamera_BackView.isAvailable()) { + mCameraBack.textureListener.onSurfaceTextureAvailable( + mCamera_BackView.getSurfaceTexture(), mCamera_BackView.getWidth(), + mCamera_BackView.getHeight()); + } else { + mCamera_BackView.setSurfaceTextureListener(mCameraBack.textureListener); + } + } + + public void Open_BackCamera() { + String[] Data = new String[5]; + + Data[0] = "BackCamera"; + Data[1] = CameraIds[0]; + Data[2] = "capture_list"; + Data[3] = "video_list"; + Data[4] = "pref_resolution_1"; + + mCameraBack = new CameraBase(this, mCamera_BackView, null, mRecordingTimeView, + Data, mRoundedThumbnailView); + } + + + public void Open_FrontCamera() { + String[] Data = new String[5]; + + Data[0] = "FrontCamera"; + Data[1] = CameraIds[1]; + Data[2] = "capture_list_1"; + Data[3] = "video_list_1"; + Data[4] = "pref_resolution_1"; + + mCameraFront = new CameraBase(this, mCamera_FrontView, null, mRecordingTimeView, + Data, mRoundedThumbnailView); + } + /** + * Checks if any of the needed Android runtime permissions are missing. + * If they are, then launch the permissions activity under one of the following conditions: + * a) The permissions dialogs have not run yet. We will ask for permission only once. + * b) If the missing permissions are critical to the app running, we will display a fatal error + * dialog. Critical permissions are: camera, microphone and storage. The app cannot run without + * them. Non-critical permission is location. + */ + private void checkPermissions() { + mHasCriticalPermissions = + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.CAMERA) == + PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.RECORD_AUDIO) == + PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.READ_EXTERNAL_STORAGE) == + PackageManager.PERMISSION_GRANTED; + + if (!mHasCriticalPermissions) { + Intent intent = new Intent(this, PermissionsActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + + if (!mHasCriticalPermissions) { + Log.v(TAG, "onCreate: Missing critical permissions."); + finish(); + return; + } + + } + + @Override + protected void onPause() { + unregisterReceiver(mUsbReceiver); + super.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + Log.e(TAG, "onResume"); + MultiCamera ic_cam = MultiCamera.getInstance(); + ic_cam.setIsCameraOrSurveillance(0); + if (ic_cam.getWhichCamera() == 0) { + openBackCamera(); + } else { + openFrontCamera(); + } + } +} diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/MultiCamera.java b/camera/MultiCameraApplication/java/com/intel/multicamera/MultiCamera.java new file mode 100644 index 0000000..68a6ae8 --- /dev/null +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/MultiCamera.java @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2019 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.multicamera; + +import android.content.ContentValues; +import android.graphics.Camera; +import android.net.Uri; + +public class MultiCamera { + private static MultiCamera ic_instance = null; + private CameraBase mTopRightCam; + private CameraBase mBotmLeftCam; + private CameraBase mBotmRightCam; + private CameraBase mTopLeftCam; + + private int mOpenCameraId; + private Uri mCurrentUri; + private ContentValues mCurrentFileInfo; + + MultiCamera() { + mWhichCamera = 0; + mIsCameraOrSurveillance = 0; + mOpenCameraId = -1; + } + public static MultiCamera getInstance() { + if (ic_instance == null) { + ic_instance = new MultiCamera(); + } + + return ic_instance; + } + + private int mWhichCamera; + + private int mIsCameraOrSurveillance; + + public int getWhichCamera() { + return mWhichCamera; + } + + public void setWhichCamera(int whichCamera) { + mWhichCamera = whichCamera; + } + + public int getIsCameraOrSurveillance() { + return mIsCameraOrSurveillance; + } + + public void setIsCameraOrSurveillance(int isCameraOrSurveillance) { + mIsCameraOrSurveillance = isCameraOrSurveillance; + } + + public Uri getCurrentUri() { + return mCurrentUri; + } + + public void setCurrentUri(Uri currentUri) { + this.mCurrentUri = currentUri; + } + + public ContentValues getCurrentFileInfo() { + return mCurrentFileInfo; + } + + public void setCurrentFileInfo(ContentValues currentFileInfo) { + this.mCurrentFileInfo = currentFileInfo; + } + + public CameraBase getTopRightCam() { + return mTopRightCam; + } + + public void setTopRightCam(CameraBase topRightCam) { + this.mTopRightCam = topRightCam; + } + + public CameraBase getBotLeftCam() { + return mBotmLeftCam; + } + + public void setBotLeftCam(CameraBase botmLeftCam) { + this.mBotmLeftCam = botmLeftCam; + } + + public CameraBase getBotRightCam() { + return mBotmRightCam; + } + + public void setBotRightCam(CameraBase botmRightCam) { + this.mBotmRightCam = botmRightCam; + } + + public CameraBase getTopLeftCam() { + return mTopLeftCam; + } + + public void setTopLeftCam(CameraBase mTopLeftCam) { + this.mTopLeftCam = mTopLeftCam; + } + + public int getOpenCameraId() { + return mOpenCameraId; + } + + public void setOpenCameraId(int openCameraId) { + mOpenCameraId = openCameraId; + } +} diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/MultiViewActivity.java b/camera/MultiCameraApplication/java/com/intel/multicamera/MultiViewActivity.java index d13f9d8..40ca55e 100644 --- a/camera/MultiCameraApplication/java/com/intel/multicamera/MultiViewActivity.java +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/MultiViewActivity.java @@ -18,7 +18,6 @@ package com.intel.multicamera; import android.Manifest; -import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -26,8 +25,6 @@ import android.content.pm.PackageManager; import android.hardware.camera2.CameraAccessException; import android.hardware.camera2.CameraManager; -import android.hardware.usb.UsbDevice; -import android.hardware.usb.UsbDeviceConnection; import android.hardware.usb.UsbManager; import android.os.AsyncTask; import android.os.Bundle; @@ -39,22 +36,24 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import java.io.IOException; -import java.util.HashMap; - -import static android.hardware.usb.UsbManager.ACTION_USB_DEVICE_ATTACHED; -import static android.hardware.usb.UsbManager.ACTION_USB_DEVICE_DETACHED; +import java.util.concurrent.TimeUnit; public class MultiViewActivity extends AppCompatActivity { - private static final String TAG = "MainActivity"; + private static final String TAG = "MultiViewActivity"; + + /** * An {@link AutoFitTextureView} for camera preview. */ private AutoFitTextureView mTopLeftCam_textureView, mTopRightCam_textureView, mBotmLeftCam_textureView, mBotmRightCam_textureView; - private ImageButton mTopLeftCam_RecordButton, mTopLeftCam_PictureButton, - mTopRightCam_PictureButton, mBotmLeftCam_PictureButton, mBotmRightCam_PictureButton, - mTopRightCam_RecordButton, mBotmLeftCam_RecordButton, mBotmRightCam_RecordButton; + private ImageButton mTopLeftCam_RecordButton, mTopLeftCam_PictureButton, mTopLeftCam_Switch, + mTopLeftCam_Split, mTopRightCam_PictureButton, mTopRightCam_RecordButton, + mTopRightCam_Switch, mTopRightCam_Split, mBotmLeftCam_PictureButton, + mBotmLeftCam_RecordButton, mBotmLeftCam_Switch, mBotmLeftCam_Split, + mBotmRightCam_PictureButton, mBotmRightCam_RecordButton, mBotRightCam_Switch, + mBotRightCam_Split; private ImageButton SettingView0, SettingView1, SettingView2, SettingView3, SettingClose0, SettingClose1, SettingClose2, SettingClose3, FullScrn0, FullScrn1, FullScrn2, FullScrn3, @@ -63,12 +62,11 @@ public class MultiViewActivity extends AppCompatActivity { private TextView mRecordingTimeView, mRecordingTimeView0, mRecordingTimeView1, mRecordingTimeView2; + private BroadcastReceiver mUsbReceiver; private int numOfCameras; private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); private FrameLayout frameView0, frameView1, frameView2, frameView3; - private CameraBase mTopRightCam, mBotmLeftCam, mBotmRightCam, mTopLeftCam; - private SettingsPrefUtil Fragment, Fragment1, Fragment2, Fragment3; public String[] CameraIds; @@ -88,7 +86,8 @@ public class MultiViewActivity extends AppCompatActivity { private int[] FrameVisibility; private boolean exitScrnFlag; - + private boolean exitRecordScrnFlag; + MultiCamera ic_camera; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -105,6 +104,7 @@ protected void onCreate(Bundle savedInstanceState) { Log.e(TAG, "onCreate"); + ic_camera = MultiCamera.getInstance(); checkPermissions(); if (!mHasCriticalPermissions) { Log.v(TAG, "onCreate: Missing critical permissions."); @@ -117,22 +117,32 @@ protected void onCreate(Bundle savedInstanceState) { FullScrn_Init(); set_FrameVisibilities(); - + + exitScrn0.setVisibility(View.GONE); + exitScrn1.setVisibility(View.GONE); + exitScrn2.setVisibility(View.GONE); + exitScrn3.setVisibility(View.GONE); + + FullScrn0.setVisibility(View.GONE); + FullScrn1.setVisibility(View.GONE); + FullScrn2.setVisibility(View.GONE); + FullScrn3.setVisibility(View.GONE); startCamera(); IntentFilter filter = new IntentFilter(); filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); // BroadcastReceiver when insert/remove the device USB plug into/from a USB port - BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { + mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) { String action = intent.getAction(); System.out.println("BroadcastReceiver Event"); if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) { - System.out.println("BroadcastReceiver USB Connected"); + System.out.println(TAG + "BroadcastReceiver USB Connected"); startCamera(); + } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { - System.out.println("BroadcastReceiver USB Disconnected"); + System.out.println(TAG + "BroadcastReceiver USB Disconnected"); startCamera(); } } @@ -142,7 +152,17 @@ public void onReceive(Context context, Intent intent) { void startCamera() { closeCamera(); + try { + TimeUnit.MILLISECONDS.sleep(100); + } catch (Exception e) { + + } GetCameraCnt(); + if (numOfCameras == 0) { + Toast.makeText(MultiViewActivity.this, "No Camera Found", Toast.LENGTH_LONG).show(); + System.out.println(TAG+" no camera found"); + return; + } updateStorageSpace(null); LinearLayout LinLayout1 = findViewById(R.id.TopLayout); LinearLayout LinLayout2 = findViewById(R.id.BtmLayout); @@ -244,6 +264,10 @@ public void GetCameraCnt() { try { CameraIds = manager.getCameraIdList(); numOfCameras = manager.getCameraIdList().length; + if (numOfCameras == 0) { + Toast.makeText(MultiViewActivity.this, "No camera found closing the application", + Toast.LENGTH_LONG).show(); + } Log.d(TAG, "Get total number of cameras present: " + manager.getCameraIdList().length); } catch (CameraAccessException e) { e.printStackTrace(); @@ -252,20 +276,38 @@ public void GetCameraCnt() { public void Open_TopLeftCam() { String[] Data = new String[5]; - ImageButton[] Buttons = new ImageButton[4]; + ImageButton[] Buttons = new ImageButton[6]; mTopLeftCam_textureView = findViewById(R.id.textureview0); if (mTopLeftCam_textureView == null) return; + mTopLeftCam_textureView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + ic_camera.setOpenCameraId(0); + closeCamera(); + ic_camera.setIsCameraOrSurveillance(0); + Intent intent = new Intent(MultiViewActivity.this, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + }); + mTopLeftCam_Switch = findViewById(R.id.camera_switch0); + mTopLeftCam_Switch.setVisibility(View.VISIBLE); mTopLeftCam_PictureButton = findViewById(R.id.Picture0); mTopLeftCam_RecordButton = findViewById(R.id.Record0); + mTopLeftCam_Split = findViewById(R.id.camera_split_view0); Buttons[0] = mTopLeftCam_PictureButton; Buttons[1] = mTopLeftCam_RecordButton; Buttons[2] = SettingView0; Buttons[3] = FullScrn0; + Buttons[4] = mTopLeftCam_Switch; + Buttons[5] = mTopLeftCam_Split; - mRecordingTimeView = findViewById(R.id.recording_time); + mRecordingTimeView = findViewById(R.id.recording_time0); Data[0] = "TopLeftCam"; Data[1] = CameraIds[0]; @@ -273,25 +315,43 @@ public void Open_TopLeftCam() { Data[3] = "video_list"; Data[4] = "pref_resolution"; - RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view); + RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view0); - mTopLeftCam = new CameraBase(this, mTopLeftCam_textureView, Buttons, mRecordingTimeView, - Data, roundedThumbnailView); + ic_camera.setTopLeftCam(new CameraBase(this, mTopLeftCam_textureView, Buttons, mRecordingTimeView, + Data, roundedThumbnailView)); } public void Open_TopRightCam() { String[] Data = new String[5]; - ImageButton[] Buttons = new ImageButton[4]; + ImageButton[] Buttons = new ImageButton[6]; mTopRightCam_textureView = findViewById(R.id.textureview1); if (mTopRightCam_textureView == null) return; + mTopRightCam_textureView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ic_camera.setOpenCameraId(1); + closeCamera(); + ic_camera.setIsCameraOrSurveillance(0); + Intent intent = new Intent(MultiViewActivity.this, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + }); + + mTopRightCam_Switch = findViewById(R.id.camera_switch1); + mTopRightCam_Switch.setVisibility(View.VISIBLE); mTopRightCam_PictureButton = findViewById(R.id.Picture1); mTopRightCam_RecordButton = findViewById(R.id.Record1); + mTopRightCam_Split = findViewById(R.id.camera_split_view1); Buttons[0] = mTopRightCam_PictureButton; Buttons[1] = mTopRightCam_RecordButton; Buttons[2] = SettingView1; Buttons[3] = FullScrn1; + Buttons[4] = mTopRightCam_Switch; + Buttons[5] = mTopRightCam_Split; Data[0] = "TopRightCam"; Data[1] = CameraIds[1]; @@ -299,27 +359,46 @@ public void Open_TopRightCam() { Data[3] = "video_list_1"; Data[4] = "pref_resolution_1"; - mRecordingTimeView0 = findViewById(R.id.recording_time0); + mRecordingTimeView0 = findViewById(R.id.recording_time1); - RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view0); + RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view1); - mTopRightCam = new CameraBase(this, mTopRightCam_textureView, Buttons, mRecordingTimeView0, - Data, roundedThumbnailView); + ic_camera.setTopRightCam(new CameraBase(this, mTopRightCam_textureView, Buttons, + mRecordingTimeView0, Data, roundedThumbnailView)); } public void Open_BotmLeftCam() { String[] Data = new String[5]; - ImageButton[] Buttons = new ImageButton[4]; + ImageButton[] Buttons = new ImageButton[6]; mBotmLeftCam_textureView = findViewById(R.id.textureview2); if (mBotmLeftCam_textureView == null) return; + mBotmLeftCam_textureView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ic_camera.setOpenCameraId(2); + closeCamera(); + Intent intent = new Intent(MultiViewActivity.this, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + ic_camera.setIsCameraOrSurveillance(0); + + } + }); + + mBotmLeftCam_Switch = findViewById(R.id.camera_switch2); + mBotmLeftCam_PictureButton = findViewById(R.id.Picture2); mBotmLeftCam_RecordButton = findViewById(R.id.Record2); + mBotmLeftCam_Split = findViewById(R.id.camera_split_view2); Buttons[0] = mBotmLeftCam_PictureButton; Buttons[1] = mBotmLeftCam_RecordButton; Buttons[2] = SettingView2; Buttons[3] = FullScrn2; + Buttons[4] = mBotmLeftCam_Switch; + Buttons[5] = mBotmLeftCam_Split; Data[0] = "BotmLeftCam"; Data[1] = CameraIds[2]; @@ -331,23 +410,40 @@ public void Open_BotmLeftCam() { RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view1); - mBotmLeftCam = new CameraBase(this, mBotmLeftCam_textureView, Buttons, mRecordingTimeView1, - Data, roundedThumbnailView); + ic_camera.setBotLeftCam(new CameraBase(this, mBotmLeftCam_textureView, Buttons, + mRecordingTimeView1, Data, roundedThumbnailView)); } public void Open_BotmRightCam() { String[] Data = new String[5]; - ImageButton[] Buttons = new ImageButton[4]; + ImageButton[] Buttons = new ImageButton[6]; mBotmRightCam_textureView = findViewById(R.id.textureview3); - if (mTopRightCam_textureView == null) return; + if (mBotmRightCam_textureView == null) return; + mBotmRightCam_textureView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ic_camera.setOpenCameraId(3); + closeCamera(); + Intent intent = new Intent(MultiViewActivity.this, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + ic_camera.setIsCameraOrSurveillance(0); + } + }); + + mBotRightCam_Switch = findViewById(R.id.camera_switch3); mBotmRightCam_PictureButton = findViewById(R.id.Picture3); mBotmRightCam_RecordButton = findViewById(R.id.Record3); + mBotRightCam_Split = findViewById(R.id.camera_split_view3); Buttons[0] = mBotmRightCam_PictureButton; Buttons[1] = mBotmRightCam_RecordButton; Buttons[2] = SettingView3; Buttons[3] = FullScrn3; + Buttons[4] = mBotRightCam_Switch; + Buttons[5] = mBotRightCam_Split; Data[0] = "BotmRightCam"; Data[1] = CameraIds[3]; @@ -359,32 +455,90 @@ public void Open_BotmRightCam() { RoundedThumbnailView roundedThumbnailView = findViewById(R.id.rounded_thumbnail_view2); - mBotmRightCam = new CameraBase(this, mBotmRightCam_textureView, Buttons, - mRecordingTimeView2, Data, roundedThumbnailView); + ic_camera.setBotRightCam(new CameraBase(this, mBotmRightCam_textureView, Buttons, + mRecordingTimeView2, Data, roundedThumbnailView)); } private void manageTopLeftCam() { frameView0.setVisibility(FrameLayout.VISIBLE); FrameVisibility[0] = frameView0.getVisibility(); - if (mTopLeftCam == null) { + if (ic_camera.getTopLeftCam() == null) { + Open_TopLeftCam(); } else if (mTopLeftCam_textureView == null) { mTopLeftCam_textureView = findViewById(R.id.textureview0); } if (mTopLeftCam_textureView.isAvailable()) { - mTopLeftCam.textureListener.onSurfaceTextureAvailable( - mTopLeftCam_textureView.getSurfaceTexture(), mTopLeftCam_textureView.getWidth(), - mTopLeftCam_textureView.getHeight()); + if (ic_camera.getTopLeftCam() != null) { + ic_camera.getTopLeftCam().textureListener.onSurfaceTextureAvailable( + mTopLeftCam_textureView.getSurfaceTexture(), + mTopLeftCam_textureView.getWidth(), + mTopLeftCam_textureView.getHeight()); + } } else { - mTopLeftCam_textureView.setSurfaceTextureListener(mTopLeftCam.textureListener); + if (ic_camera.getTopLeftCam() != null && mTopLeftCam_textureView != null) { + mTopLeftCam_textureView.setSurfaceTextureListener( + ic_camera.getTopLeftCam().textureListener); + } } + findViewById(R.id.camera_switch0).setVisibility(View.VISIBLE); + } + public void hideCameraSwitchButton() { + findViewById(R.id.camera_switch0).setVisibility(View.GONE); + findViewById(R.id.camera_switch1).setVisibility(View.GONE); + findViewById(R.id.camera_switch2).setVisibility(View.GONE); + findViewById(R.id.camera_switch3).setVisibility(View.GONE); + + findViewById(R.id.imageView0).setVisibility(View.VISIBLE); + findViewById(R.id.imageView1).setVisibility(View.VISIBLE); + findViewById(R.id.imageView2).setVisibility(View.VISIBLE); + findViewById(R.id.imageView3).setVisibility(View.VISIBLE); + } + + public void visibleCameraSwitchButton() { + exitScrn0.setVisibility(View.GONE); + exitScrn1.setVisibility(View.GONE); + exitScrn2.setVisibility(View.GONE); + exitScrn3.setVisibility(View.GONE); + + FullScrn0.setVisibility(View.GONE); + FullScrn1.setVisibility(View.GONE); + FullScrn2.setVisibility(View.GONE); + FullScrn3.setVisibility(View.GONE); + + findViewById(R.id.camera_switch0).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch1).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch2).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch3).setVisibility(View.VISIBLE); + + findViewById(R.id.imageView0).setVisibility(View.GONE); + findViewById(R.id.imageView1).setVisibility(View.GONE); + findViewById(R.id.imageView2).setVisibility(View.GONE); + findViewById(R.id.imageView3).setVisibility(View.GONE); } + void enableSingleCameraButtons() { + findViewById(R.id.camera_switch0).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch1).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch2).setVisibility(View.VISIBLE); + findViewById(R.id.camera_switch3).setVisibility(View.VISIBLE); + + exitScrn0.setVisibility(View.GONE); + exitScrn1.setVisibility(View.GONE); + exitScrn2.setVisibility(View.GONE); + exitScrn3.setVisibility(View.GONE); + + FullScrn0.setVisibility(View.GONE); + FullScrn1.setVisibility(View.GONE); + FullScrn2.setVisibility(View.GONE); + FullScrn3.setVisibility(View.GONE); + + } private void manageTopRightCam() { frameView1.setVisibility(FrameLayout.VISIBLE); FrameVisibility[1] = frameView1.getVisibility(); - if (mTopRightCam == null) { + if (ic_camera.getTopRightCam() == null) { Open_TopRightCam(); } else if (mTopRightCam_textureView == null) { @@ -392,18 +546,19 @@ private void manageTopRightCam() { } if (mTopRightCam_textureView.isAvailable()) { - mTopRightCam.textureListener.onSurfaceTextureAvailable( + ic_camera.getTopRightCam().textureListener.onSurfaceTextureAvailable( mTopRightCam_textureView.getSurfaceTexture(), mTopRightCam_textureView.getWidth(), mTopRightCam_textureView.getHeight()); } else { - mTopRightCam_textureView.setSurfaceTextureListener(mTopRightCam.textureListener); + mTopRightCam_textureView.setSurfaceTextureListener( + ic_camera.getTopRightCam().textureListener); } } private void manageBotmLeftCam() { frameView2.setVisibility(FrameLayout.VISIBLE); FrameVisibility[2] = frameView2.getVisibility(); - if (mBotmLeftCam == null) { + if (ic_camera.getBotLeftCam() == null) { Open_BotmLeftCam(); } else if (mBotmLeftCam_textureView == null) { @@ -411,18 +566,19 @@ private void manageBotmLeftCam() { } if (mBotmLeftCam_textureView.isAvailable()) { - mBotmLeftCam.textureListener.onSurfaceTextureAvailable( + ic_camera.getBotLeftCam().textureListener.onSurfaceTextureAvailable( mBotmLeftCam_textureView.getSurfaceTexture(), mBotmLeftCam_textureView.getWidth(), mBotmLeftCam_textureView.getHeight()); } else { - mBotmLeftCam_textureView.setSurfaceTextureListener(mBotmLeftCam.textureListener); + mBotmLeftCam_textureView.setSurfaceTextureListener( + ic_camera.getBotLeftCam().textureListener); } } private void manageBotmRightCam() { frameView3.setVisibility(FrameLayout.VISIBLE); FrameVisibility[3] = frameView3.getVisibility(); - if (mBotmRightCam == null) { + if (ic_camera.getBotRightCam() == null) { Open_BotmRightCam(); } else if (mBotmRightCam_textureView == null) { @@ -430,38 +586,52 @@ private void manageBotmRightCam() { } if (mBotmRightCam_textureView.isAvailable()) { - mBotmRightCam.textureListener.onSurfaceTextureAvailable( + ic_camera.getBotRightCam().textureListener.onSurfaceTextureAvailable( mBotmRightCam_textureView.getSurfaceTexture(), mBotmRightCam_textureView.getWidth(), mBotmRightCam_textureView.getHeight()); } else { - mBotmRightCam_textureView.setSurfaceTextureListener(mBotmRightCam.textureListener); + mBotmRightCam_textureView.setSurfaceTextureListener( + ic_camera.getBotRightCam().textureListener); } } @Override protected void onResume() { super.onResume(); - Log.e(TAG, "onResume"); - - + Log.e(TAG, " onResume"); + //startCamera(); + hideCameraSwitchButton(); } - private void closeCamera() { - if (null != mTopLeftCam) mTopLeftCam.closeCamera(); + public void closeCamera() { + if (null != ic_camera.getTopLeftCam()) { + ic_camera.getTopLeftCam().closeCamera(); + ic_camera.setTopLeftCam(null); + } - if (null != mTopRightCam) mTopRightCam.closeCamera(); + if (null != ic_camera.getTopRightCam()) { + ic_camera.getTopRightCam().closeCamera(); + ic_camera.setTopRightCam(null); + } - if (null != mBotmRightCam) mBotmRightCam.closeCamera(); + if (null != ic_camera.getBotRightCam()) { + ic_camera.getBotRightCam().closeCamera(); + ic_camera.setBotRightCam(null); + } - if (null != mBotmLeftCam) mBotmLeftCam.closeCamera(); + if (null != ic_camera.getBotLeftCam()) { + ic_camera.getBotLeftCam().closeCamera(); + ic_camera.setBotLeftCam(null); + } } @Override protected void onPause() { - Log.e(TAG, "onPause"); + System.out.println("onPause"); super.onPause(); - closeCamera(); + unregisterReceiver(mUsbReceiver); + // closeCamera(); } public void settingView(View view) { @@ -601,10 +771,7 @@ public void settingClose(View view) { else exitScrn0.setVisibility(View.VISIBLE); - mTopLeftCam_RecordButton.setVisibility(View.VISIBLE); - mTopLeftCam_PictureButton.setVisibility(View.VISIBLE); - - mTopLeftCam.createCameraPreview(); + ic_camera.getTopLeftCam().createCameraPreview(); break; case R.id.mSettingClose1: @@ -621,10 +788,7 @@ public void settingClose(View view) { else exitScrn1.setVisibility(View.VISIBLE); - mTopRightCam_RecordButton.setVisibility(View.VISIBLE); - mTopRightCam_PictureButton.setVisibility(View.VISIBLE); - - mTopRightCam.createCameraPreview(); + ic_camera.getTopRightCam().createCameraPreview(); break; case R.id.mSettingClose2: @@ -640,10 +804,7 @@ public void settingClose(View view) { else exitScrn2.setVisibility(View.VISIBLE); - mBotmLeftCam_RecordButton.setVisibility(View.VISIBLE); - mBotmLeftCam_PictureButton.setVisibility(View.VISIBLE); - - mBotmLeftCam.createCameraPreview(); + ic_camera.getBotLeftCam().createCameraPreview(); break; case R.id.mSettingClose3: @@ -659,10 +820,7 @@ public void settingClose(View view) { else exitScrn3.setVisibility(View.VISIBLE); - mBotmRightCam_RecordButton.setVisibility(View.VISIBLE); - mBotmRightCam_PictureButton.setVisibility(View.VISIBLE); - - mBotmRightCam.createCameraPreview(); + ic_camera.getBotRightCam().createCameraPreview(); break; @@ -680,67 +838,172 @@ public void enterFullScreen(View view) { switch (view.getId()) { case R.id.imageView0: - this.setTitle("TopLeftCam"); - exitScrnFlag = true; - exitScrn0.setVisibility(View.VISIBLE); - FullScrn0.setVisibility(View.GONE); + case R.id.Picture0: + ic_camera.setOpenCameraId(0); + break; + case R.id.Record0: + this.setTitle("TopLeftCam"); + if (exitRecordScrnFlag == true) { + + this.setTitle("MultiCamera"); + exitRecordScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } + FullScrn0.setVisibility(View.VISIBLE); + + exitScrn0.setVisibility(View.GONE); + + FrameVisibility[1] = frameView1.getVisibility(); + } else { + exitRecordScrnFlag = true; + exitScrn0.setVisibility(View.GONE); + FullScrn0.setVisibility(View.GONE); frameView1.setVisibility(View.GONE); - LinLayout2.setVisibility(View.GONE); - + LinLayout2.setVisibility(View.GONE); + } break; case R.id.exitFullScreen0: this.setTitle("MultiCamera"); exitScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); - FullScrn0.setVisibility(View.VISIBLE); - - exitScrn0.setVisibility(View.GONE); - - switch (FrameVisibility[1]) { - case View.VISIBLE: - - frameView1.setVisibility(View.VISIBLE); - - break; + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); - case View.INVISIBLE: + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); - frameView1.setVisibility(View.INVISIBLE); + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); - break; - default: - break; + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); } + FullScrn0.setVisibility(View.VISIBLE); - FrameVisibility[1] = frameView1.getVisibility(); + exitScrn0.setVisibility(View.GONE); - LinLayout2.setVisibility(View.VISIBLE); + FrameVisibility[1] = frameView1.getVisibility(); break; case R.id.imageView1: + case R.id.Picture1: + ic_camera.setOpenCameraId(1); + break; + case R.id.Record1: this.setTitle("TopRightCam"); - exitScrnFlag = true; - FullScrn1.setVisibility(View.GONE); - exitScrn1.setVisibility(View.VISIBLE); + if (exitRecordScrnFlag == true) { + this.setTitle("MultiCamera"); + exitRecordScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } - frameView0.setVisibility(View.GONE); - LinLayout2.setVisibility(View.GONE); + FullScrn1.setVisibility(View.VISIBLE); + exitScrn1.setVisibility(View.GONE); + switch (FrameVisibility[0]) { + case View.VISIBLE: + frameView0.setVisibility(View.VISIBLE); + break; + + case View.INVISIBLE: + + frameView0.setVisibility(View.INVISIBLE); + + break; + default: + break; + } + + FrameVisibility[0] = frameView0.getVisibility(); + } else { + exitRecordScrnFlag = true; + FullScrn1.setVisibility(View.GONE); + exitScrn1.setVisibility(View.GONE); + + frameView0.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + } break; case R.id.exitFullScreen1: this.setTitle("MultiCamera"); exitScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } + FullScrn1.setVisibility(View.VISIBLE); exitScrn1.setVisibility(View.GONE); switch (FrameVisibility[0]) { case View.VISIBLE: - frameView0.setVisibility(View.VISIBLE); - break; case View.INVISIBLE: @@ -753,26 +1016,96 @@ public void enterFullScreen(View view) { } FrameVisibility[0] = frameView0.getVisibility(); - - LinLayout2.setVisibility(View.VISIBLE); - break; case R.id.imageView2: + case R.id.Picture2: + ic_camera.setOpenCameraId(2); + break; + case R.id.Record2: this.setTitle("BotmLeftCam"); + if (exitRecordScrnFlag == true) { + this.setTitle("MultiCamera"); + + exitRecordScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } - exitScrnFlag = true; - FullScrn2.setVisibility(View.GONE); - exitScrn2.setVisibility(View.VISIBLE); + FullScrn2.setVisibility(View.VISIBLE); + exitScrn2.setVisibility(View.GONE); - frameView3.setVisibility(View.GONE); - LinLayout1.setVisibility(View.GONE); + switch (FrameVisibility[3]) { + case View.VISIBLE: + + frameView3.setVisibility(View.VISIBLE); + + break; + + case View.INVISIBLE: + + frameView3.setVisibility(View.INVISIBLE); + break; + default: + break; + } + + FrameVisibility[3] = frameView3.getVisibility(); + + } else { + exitRecordScrnFlag = true; + FullScrn2.setVisibility(View.GONE); + exitScrn2.setVisibility(View.GONE); + + frameView3.setVisibility(View.GONE); + LinLayout1.setVisibility(View.GONE); + } break; case R.id.exitFullScreen2: this.setTitle("MultiCamera"); exitScrnFlag = false; + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } + FullScrn2.setVisibility(View.VISIBLE); exitScrn2.setVisibility(View.GONE); @@ -793,23 +1126,94 @@ public void enterFullScreen(View view) { } FrameVisibility[3] = frameView3.getVisibility(); - - LinLayout1.setVisibility(View.VISIBLE); - break; case R.id.imageView3: - this.setTitle("BotmRightCam"); - exitScrnFlag = true; - FullScrn3.setVisibility(View.GONE); - exitScrn3.setVisibility(View.VISIBLE); + case R.id.Picture3: + ic_camera.setOpenCameraId(3); + break; + case R.id.Record3: + if (exitRecordScrnFlag == true) { + this.setTitle("MultiCamera"); + exitRecordScrnFlag = false; + + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } - frameView2.setVisibility(View.GONE); - LinLayout1.setVisibility(View.GONE); + FullScrn3.setVisibility(View.VISIBLE); + exitScrn3.setVisibility(View.GONE); + + switch (FrameVisibility[2]) { + case View.VISIBLE: + + frameView2.setVisibility(View.VISIBLE); + + break; + + case View.INVISIBLE: + + frameView2.setVisibility(View.INVISIBLE); + + break; + default: + break; + } + FrameVisibility[2] = frameView2.getVisibility(); + } else { + this.setTitle("BotmRightCam"); + exitRecordScrnFlag = true; + FullScrn3.setVisibility(View.GONE); + exitScrn3.setVisibility(View.GONE); + + frameView2.setVisibility(View.GONE); + LinLayout1.setVisibility(View.GONE); + } break; case R.id.exitFullScreen3: this.setTitle("MultiCamera"); exitScrnFlag = false; + + LinLayout1.setVisibility(View.GONE); + LinLayout2.setVisibility(View.GONE); + if (numOfCameras == 1) { + frameView1.setVisibility(FrameLayout.GONE); + LinLayout1.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 2) { + LinLayout1.setVisibility(View.VISIBLE); + frameView1.setVisibility(FrameLayout.VISIBLE); + + } else if (numOfCameras == 3) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else if (numOfCameras == 4) { + LinLayout1.setVisibility(View.VISIBLE); + LinLayout2.setVisibility(View.VISIBLE); + + } else { + Log.d(TAG, "onResume No CAMERA CONNECTED"); + } + FullScrn3.setVisibility(View.VISIBLE); exitScrn3.setVisibility(View.GONE); @@ -830,13 +1234,19 @@ public void enterFullScreen(View view) { } FrameVisibility[2] = frameView2.getVisibility(); - - LinLayout1.setVisibility(View.VISIBLE); - break; default: break; } + + closeCamera(); + + Intent intent = new Intent(MultiViewActivity.this, SingleCameraActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + ic_camera.setIsCameraOrSurveillance(0); + } protected static long getStorageSpaceBytes() { diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/PermissionsActivity.java b/camera/MultiCameraApplication/java/com/intel/multicamera/PermissionsActivity.java index 3098a61..708fe81 100644 --- a/camera/MultiCameraApplication/java/com/intel/multicamera/PermissionsActivity.java +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/PermissionsActivity.java @@ -214,7 +214,7 @@ public void onRequestPermissionsResult(int requestCode, String permissions[], } private void handlePermissionsSuccess() { - Intent intent = new Intent(this, MultiViewActivity.class); + Intent intent = new Intent(this, FullScreenActivity.class); startActivity(intent); finish(); } diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/PhotoPreview.java b/camera/MultiCameraApplication/java/com/intel/multicamera/PhotoPreview.java new file mode 100644 index 0000000..70854e8 --- /dev/null +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/PhotoPreview.java @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * Copyright (c) 2019 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.multicamera; + +import android.app.Activity; +import android.app.Dialog; +import android.content.ContentValues; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraManager; +import android.net.Uri; +import android.util.Log; +import android.util.SparseIntArray; +import android.view.Surface; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import java.io.File; +import java.util.Optional; + +public class PhotoPreview { + private static final String TAG = "PhotoPreview"; + private Uri mCurrentUri; + + private MultiCamera ic_camera; + private RoundedThumbnailView mRoundedThumbnailView; + private Activity mActivity; + FrameLayout roundedThumbnailViewControlLayout; + private String mCameraId; + private int mSensorOrientation; + private static final SparseIntArray ORIENTATIONS = new SparseIntArray(); + + static { + ORIENTATIONS.append(Surface.ROTATION_0, 90); + ORIENTATIONS.append(Surface.ROTATION_90, 0); + ORIENTATIONS.append(Surface.ROTATION_180, 270); + ORIENTATIONS.append(Surface.ROTATION_270, 180); + } + + public PhotoPreview(Activity activity, RoundedThumbnailView roundedThumbnailView, String cameraId) { + mActivity = activity; + ic_camera = MultiCamera.getInstance(); + mRoundedThumbnailView = roundedThumbnailView; + roundedThumbnailViewControlLayout = mActivity.findViewById(R.id.control1); + mCameraId = cameraId; + RoundedThumbnail_setOnClickListners(); + } + private void RoundedThumbnail_setOnClickListners() { + mRoundedThumbnailView.setCallback(new RoundedThumbnailView.Callback() { + @Override + public void onHitStateFinished() { + System.out.println("RoundedThumbnail_setOnClickListners"); + ImageView preView; + final ImageButton btnDelete, playButton, btnBack, details; + FrameLayout previewLayout; + + String mimeType = Utils.getMimeTypeFromURI(mActivity, ic_camera.getCurrentUri()); + + previewLayout = mActivity.findViewById(R.id.previewLayout); + previewLayout.setVisibility(View.VISIBLE); + + btnDelete = mActivity.findViewById(R.id.control_delete); + playButton = mActivity.findViewById(R.id.play_button); + preView = mActivity.findViewById(R.id.preview); + btnBack = mActivity.findViewById(R.id.control_back); + details = mActivity.findViewById(R.id.control_info); + details.setVisibility(View.VISIBLE); + + btnBack.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FrameLayout previewLayout; + previewLayout = mActivity.findViewById(R.id.previewLayout); + previewLayout.setVisibility(View.GONE); + + mRoundedThumbnailView.hideThumbnail(); + } + }); + + btnDelete.setOnClickListener(new View.OnClickListener() { + ImageView preView; + + @Override + public void onClick(View v) { + preView = mActivity.findViewById(R.id.preview); + + Uri uri = ic_camera.getCurrentUri(); + File file = new File(Utils.getRealPathFromURI(mActivity, uri)); + if (file.exists()) { + Log.v(TAG, " Thumbnail Preview File Deleted "); + file.delete(); + // request scan + Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); + scanIntent.setData(Uri.fromFile(file)); + mActivity.sendBroadcast(scanIntent); + preView.setImageResource(android.R.color.background_dark); + details.setVisibility(View.INVISIBLE); + } + } + }); + + details.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + showDetailsDialog(ic_camera.getCurrentFileInfo()); + } + }); + + if (mimeType.compareTo("video/mp4") == 0) { + VideoPreview(playButton, preView); + + } else { + photoPreview(playButton, preView); + } + } + }); + } + + + private void showDetailsDialog(ContentValues info) { + Optional details = Utils.getMediaDetails(mActivity, info); + if (!details.isPresent()) { + return; + } + Dialog detailDialog = DetailsDialog.create(mActivity, details.get()); + detailDialog.show(); + } + + private void VideoPreview(ImageButton playButton, ImageView preView) { + final Optional bitmap = + Utils.getVideoThumbnail(mActivity.getContentResolver(), ic_camera.getCurrentUri()); + if (bitmap.isPresent()) { + playButton.setVisibility(View.VISIBLE); + + playButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Utils.playVideo(mActivity, ic_camera.getCurrentUri(), TAG); + } + }); + + preView.setVisibility(View.VISIBLE); + preView.setImageBitmap(bitmap.get()); + + } else { + Log.e(TAG, "No bitmap image found: "); + } + } + + private void photoPreview(ImageButton playButton, ImageView preView) { + Uri PhotoUri = ic_camera.getCurrentUri(); + + preView.setVisibility(View.VISIBLE); + playButton.setVisibility(View.GONE); + preView.setImageURI(PhotoUri); + } + + public void showImageThumbnail(File ImageFile) { + final int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + final Optional bitmap = + Utils.generateThumbnail(ImageFile, roundedThumbnailViewControlLayout.getWidth(), + roundedThumbnailViewControlLayout.getMeasuredHeight()); + + if (bitmap.isPresent()) { + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mRoundedThumbnailView.startRevealThumbnailAnimation("photo taken"); + mRoundedThumbnailView.setThumbnail(bitmap.get(), getOrientation(rotation)); + } + }); + + } else { + Log.e(TAG, "No bitmap image found: "); + } + } + + private int getOrientation(int rotation) { + // Sensor orientation is 90 for most devices, or 270 for some devices (eg. Nexus 5X) + // We have to take that into account and rotate JPEG properly. + // For devices with orientation of 90, we simply return our mapping from ORIENTATIONS. + // For devices with orientation of 270, we need to rotate the JPEG 180 degrees. + try { + CameraManager manager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE); + CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId); + mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); + } catch (Exception e) { + + } + return (ORIENTATIONS.get(rotation) + mSensorOrientation + 270) % 360; + } + + + public void showVideoThumbnail() { + mRoundedThumbnailView.startRevealThumbnailAnimation("Video taken"); + + final Optional bitmap = + Utils.getVideoThumbnail(mActivity.getContentResolver(), ic_camera.getCurrentUri()); + + if (bitmap.isPresent()) { + mRoundedThumbnailView.setThumbnail(bitmap.get(), 0); + } else { + Log.e(TAG, "No bitmap image found: "); + } + } +} diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/SingleCameraActivity.java b/camera/MultiCameraApplication/java/com/intel/multicamera/SingleCameraActivity.java new file mode 100644 index 0000000..f07a2a7 --- /dev/null +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/SingleCameraActivity.java @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2019 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.multicamera; + +import android.Manifest; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraManager; +import android.hardware.usb.UsbManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; + +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import static com.intel.multicamera.MultiViewActivity.updateStorageSpace; + +public class SingleCameraActivity extends AppCompatActivity { + private static final String TAG = "SingleCameraActivity"; + private boolean mHasCriticalPermissions; + + private int numOfCameras; + private AutoFitTextureView mCamera_BackView, mCamera_FrontView; + + private ImageButton mCameraSwitch, mCameraPicture, mCameraRecord, mCameraSplit, mSettings; + public String[] CameraIds; + MultiCamera mCameraInst; + private TextView mRecordingTimeView; + private boolean mIsRecordingVideo; + private CameraBase mCamera; + private RoundedThumbnailView mRoundedThumbnailView; + private BroadcastReceiver mUsbReceiver; + private long mLastClickTime = 0; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setHomeButtonEnabled(true); + } + + setContentView(R.layout.activity_full_screen); + + mIsRecordingVideo = false; + mCameraInst = MultiCamera.getInstance(); + mCameraSwitch = findViewById(R.id.camera_switch); + mCameraSwitch.setVisibility(View.VISIBLE); + if (mCameraInst.getOpenCameraId() == 2 || mCameraInst.getOpenCameraId() == 3) + mCameraSwitch.setVisibility(View.GONE); + mCameraPicture = findViewById(R.id.Picture); + mCameraRecord = findViewById(R.id.Record); + mCameraSplit = findViewById(R.id.camera_split_view); + mRecordingTimeView = findViewById(R.id.recording_time); + mSettings = findViewById(R.id.SettingView); + mRoundedThumbnailView = findViewById(R.id.rounded_thumbnail_view); + + checkPermissions(); + OpenCamera(); + + IntentFilter filter = new IntentFilter(); + filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED); + filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED); + + // BroadcastReceiver when insert/remove the device USB plug into/from a USB port + mUsbReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + System.out.println("BroadcastReceiver Event"); + if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) { + System.out.println(TAG+"BroadcastReceiver USB Connected"); + OpenCamera(); + + } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) { + System.out.println(TAG+"BroadcastReceiver USB Disconnected"); + OpenCamera(); + } + + } + }; + + registerReceiver(mUsbReceiver , filter); + + mCameraSwitch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + MultiCamera ic_camera = MultiCamera.getInstance(); + if (ic_camera.getWhichCamera() == 0) { + ic_camera.setOpenCameraId(1); + OpenCamera(); + ic_camera.setWhichCamera(1); + Log.i(TAG,"Opened front camera"); + } + else { + ic_camera.setOpenCameraId(0); + OpenCamera(); + ic_camera.setWhichCamera(0); + Log.i(TAG,"Opened back camera"); + } + } + }); + + mCameraSplit.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + MultiCamera ic_camera = MultiCamera.getInstance(); + ic_camera.setIsCameraOrSurveillance(1); + Intent intent = new Intent(SingleCameraActivity.this, MultiViewActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + + } + }); + + mCameraPicture.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + mCamera.takePicture(); + + } + }); + + mCameraRecord.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (SystemClock.elapsedRealtime() - mLastClickTime < 1000) { + return; + } + mLastClickTime = SystemClock.elapsedRealtime(); + + try { + if (mIsRecordingVideo) { + mIsRecordingVideo = false; + + mCamera.getmRecord().stopRecordingVideo(); + mCamera.getmRecord().showRecordingUI(false); + mCamera.getmPhoto().showVideoThumbnail(); + + mCameraSwitch.setVisibility(View.VISIBLE); + mCameraPicture.setVisibility(View.VISIBLE); + mCameraRecord.setImageResource(R.drawable.ic_capture_video); + mCameraSplit.setVisibility(View.VISIBLE); + mSettings.setVisibility(View.VISIBLE); + } else { + mIsRecordingVideo =true; + + mCamera.getmRecord().startRecordingVideo(); + + mCamera.getmRecord().showRecordingUI(true); + mSettings.setVisibility(View.GONE); + mCameraSwitch.setVisibility(View.GONE); + mCameraPicture.setVisibility(View.GONE); + mCameraRecord.setImageResource(R.drawable.ic_stop_normal); + mCameraSplit.setVisibility(View.GONE); + } + } catch (Exception e) { + System.out.println(TAG + "exception during record"); + } + } + }); + } + + public void OpenCamera() { + closeCamera(); + + GetCameraCnt(); + if (numOfCameras == 0) { + Toast.makeText(SingleCameraActivity.this, "No Camera Found", Toast.LENGTH_LONG).show(); + System.out.println(TAG+" no camera found"); + return; + } + if (numOfCameras == 1) { + findViewById(R.id.camera_switch).setVisibility(View.GONE); + findViewById(R.id.camera_split_view).setVisibility(View.GONE); + } + + updateStorageSpace(null); + + Open_Camera(); + } + + private void closeCamera() { + + if (null != mCamera) { + mCamera.closeCamera(); + mCamera = null; + } + } + + + public void GetCameraCnt() { + CameraManager manager = (CameraManager)getSystemService(Context.CAMERA_SERVICE); + + try { + CameraIds = manager.getCameraIdList(); + numOfCameras = manager.getCameraIdList().length; + if (numOfCameras == 0) { + Toast.makeText(SingleCameraActivity.this, "No camera found, closing the application", + Toast.LENGTH_LONG).show(); + } + Log.d(TAG, "Get total number of cameras present: " + manager.getCameraIdList().length); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void Open_Camera() { + mCamera_BackView = findViewById(R.id.textureview); + if (mCamera_BackView == null) { + Log.e(TAG, "fail to find surface for back camera"); + return; + } + + if (mCamera == null) { + Open_Camera_ById(); + } + if (mCamera_BackView.isAvailable()) { + mCamera.textureListener.onSurfaceTextureAvailable( + mCamera_BackView.getSurfaceTexture(), mCamera_BackView.getWidth(), + mCamera_BackView.getHeight()); + } else { + mCamera_BackView.setSurfaceTextureListener(mCamera.textureListener); + } + } + + public void Open_Camera_ById() { + String[] Data = new String[5]; + + Data[0] = "BackCamera"; + Data[1] = CameraIds[mCameraInst.getOpenCameraId()]; + Data[2] = "capture_list"; + Data[3] = "video_list"; + Data[4] = "pref_resolution_1"; + + mCamera = new CameraBase(this, mCamera_BackView, null, mRecordingTimeView, + Data, mRoundedThumbnailView); + } + + /** + * Checks if any of the needed Android runtime permissions are missing. + * If they are, then launch the permissions activity under one of the following conditions: + * a) The permissions dialogs have not run yet. We will ask for permission only once. + * b) If the missing permissions are critical to the app running, we will display a fatal error + * dialog. Critical permissions are: camera, microphone and storage. The app cannot run without + * them. Non-critical permission is location. + */ + private void checkPermissions() { + mHasCriticalPermissions = + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.CAMERA) == + PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.RECORD_AUDIO) == + PackageManager.PERMISSION_GRANTED && + ActivityCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.READ_EXTERNAL_STORAGE) == + PackageManager.PERMISSION_GRANTED; + + if (!mHasCriticalPermissions) { + Intent intent = new Intent(this, PermissionsActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivity(intent); + finish(); + } + + if (!mHasCriticalPermissions) { + Log.v(TAG, "onCreate: Missing critical permissions."); + finish(); + return; + } + + } + + + @Override + protected void onPause() { + unregisterReceiver(mUsbReceiver); + super.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + Log.e(TAG, " onResume"); + } +} diff --git a/camera/MultiCameraApplication/java/com/intel/multicamera/VideoRecord.java b/camera/MultiCameraApplication/java/com/intel/multicamera/VideoRecord.java new file mode 100644 index 0000000..2c3cd2f --- /dev/null +++ b/camera/MultiCameraApplication/java/com/intel/multicamera/VideoRecord.java @@ -0,0 +1,740 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2019 Intel Corporation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intel.multicamera; + +import android.app.Activity; +import android.content.ContentValues; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Matrix; +import android.graphics.RectF; +import android.graphics.SurfaceTexture; +import android.hardware.camera2.CameraAccessException; +import android.hardware.camera2.CameraCaptureSession; +import android.hardware.camera2.CameraCharacteristics; +import android.hardware.camera2.CameraDevice; +import android.hardware.camera2.CameraManager; +import android.hardware.camera2.CameraMetadata; +import android.hardware.camera2.CaptureRequest; +import android.media.AudioDeviceInfo; +import android.media.AudioManager; +import android.media.CamcorderProfile; +import android.media.MediaRecorder; +import android.net.Uri; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Message; +import android.os.SystemClock; +import android.provider.MediaStore; +import android.util.Log; +import android.util.Size; +import android.util.SparseIntArray; +import android.view.Surface; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.preference.PreferenceManager; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static com.intel.multicamera.SettingsPrefUtil.SIZE_HD; + +public class VideoRecord implements MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener{ + + private static final String TAG = "VideoRecord"; + private CameraDevice mCameraDevice; + private AutoFitTextureView mTextureView; + private Activity mActivity; + private boolean mIsRecordingVideo; + private CameraCaptureSession cameraCaptureSessions; + private CaptureRequest.Builder captureRequestBuilder; + private SharedPreferences settings; + private MediaRecorder mMediaRecorder; + private ContentValues mCurrentVideoValues; + private String mVideoFilename, mCameraId; + private int mSensorOrientation; + private boolean mRecordingTimeCountsDown; + private Handler mBackgroundHandler; + private final Handler mHandler; + private static final int SENSOR_ORIENTATION_DEFAULT_DEGREES = 90; + private static final int SENSOR_ORIENTATION_INVERSE_DEGREES = 270; + private static final int MSG_UPDATE_RECORD_TIME = 5; + private static final SparseIntArray DEFAULT_ORIENTATIONS = new SparseIntArray(); + private static final SparseIntArray INVERSE_ORIENTATIONS = new SparseIntArray(); + private Size previewSize; + private long mRecordingStartTime; + private TextView mRecordingTimeView; + private String mVideoKey, mSettingsKey; + + private CameraBase mCameraBase; + private MultiCamera ic_camera; + static final Size SIZE_720P = new Size(1280, 720); + static final Size SIZE_480P = new Size(640, 480); + + public VideoRecord(CameraBase cameraBase, String videoKey, String cameraId, + AutoFitTextureView textureView, Activity activity, TextView recordingView, + String settingsKey) { + mCameraBase = cameraBase; + mTextureView = textureView; + mActivity = activity; + mVideoKey = videoKey; + mCameraId = cameraId; + mSettingsKey = settingsKey; + previewSize = SIZE_720P; + mRecordingTimeView = recordingView; + mRecordingTimeCountsDown = false; + mHandler = new MainHandler(); + ic_camera = MultiCamera.getInstance(); + } + /* Recording Start*/ + public void startRecordingVideo() { + if (null == mCameraDevice || !mTextureView.isAvailable()) { + return; + } + MultiViewActivity.updateStorageSpace(new MultiViewActivity.OnStorageUpdateDoneListener() { + @Override + public void onStorageUpdateDone(long bytes) throws IOException, CameraAccessException { + if (bytes <= Utils.LOW_STORAGE_THRESHOLD_BYTES) { + Log.w(TAG, "Storage issue, ignore the start request"); + Toast.makeText(mActivity, "LOW_STORAGE", Toast.LENGTH_SHORT).show(); + } else { + CamcorderProfile mProfile; + mProfile = getSelectedCamorderProfile(); + setUpMediaRecorder(mProfile); + startRecorder(mProfile); + } + } + }); + } + + + // from MediaRecorder.OnErrorListener + @Override + public void onError(MediaRecorder mr, int what, int extra) { + Log.e(TAG, "MediaRecorder error. what=" + what + ". extra=" + extra); + if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { + // We may have run out of space on the sdcard. + stopRecordingVideo(); + MultiViewActivity.updateStorageSpace(null); + } + } + + + // from MediaRecorder.OnInfoListener + @Override + public void onInfo(MediaRecorder mr, int what, int extra) { + String[] VideofileDetails = new String[0]; + if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING) { + Toast.makeText(mActivity, R.string.video_reach_size_limit, Toast.LENGTH_SHORT).show(); + + if (mIsRecordingVideo) { + saveVideo(); + + VideofileDetails = Utils.generateFileDetails(Utils.MEDIA_TYPE_VIDEO); + if (VideofileDetails == null || VideofileDetails.length < 5) { + Log.e(TAG, "setUpMediaRecorder Invalid file details"); + return; + } + + mVideoFilename = VideofileDetails[3]; + + CamcorderProfile mProfile = getSelectedCamorderProfile(); + + mCurrentVideoValues = Utils.getContentValues( + Utils.MEDIA_TYPE_VIDEO, VideofileDetails, mProfile.videoFrameWidth, + mProfile.videoFrameHeight, 0, 0); + + try { + mMediaRecorder.setNextOutputFile(new File(VideofileDetails[3])); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + MultiViewActivity.updateStorageSpace(null); + } + + public void stopRecordingVideo() { + mHandler.removeMessages(MSG_UPDATE_RECORD_TIME); + mIsRecordingVideo = false; + + releaseMedia(); + + createCameraPreview(); + saveVideo(); + } + + + private Size getSelectedDimension(String Key) { + settings = PreferenceManager.getDefaultSharedPreferences(mActivity); + + Size mDimensions = SIZE_720P; + + if (Key.compareTo(mVideoKey) == 0) { + CamcorderProfile mProfile; + + settings = PreferenceManager.getDefaultSharedPreferences(mActivity); + + String videoQuality = settings.getString(mVideoKey, SIZE_HD); + + int quality = SettingsPrefUtil.getFromSetting(videoQuality); + + mProfile = CamcorderProfile.get(0, quality); + + mDimensions = new Size(mProfile.videoFrameWidth, mProfile.videoFrameHeight); + + } + + return mDimensions; + } + + public void createCameraPreview() { + try { + + closePreviewSession(); + + SurfaceTexture texture = mTextureView.getSurfaceTexture(); + if (texture == null) return; + + Surface surface = new Surface(texture); + + String Key = GetChnagedPrefKey(); + + if(Key == null) + return; + previewSize = getSelectedDimension(Key); + + if(previewSize == null) + return; + + if (previewSize.getWidth() == 640 || previewSize.getWidth() == 320) { + previewSize = SIZE_480P; + + } else if (previewSize.getWidth() == 1280 || previewSize.getWidth() == 1920) { + previewSize = SIZE_720P; + } + + Log.i(TAG, "Previewing with " + Key + " " + previewSize.getWidth() + " x " + + previewSize.getHeight()); + + texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); + + adjustAspectRatio(previewSize.getWidth(), previewSize.getHeight()); + + captureRequestBuilder = + mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW); + + captureRequestBuilder.addTarget(surface); + + mCameraDevice.createCaptureSession( + Arrays.asList(surface), new CameraCaptureSession.StateCallback() { + @Override + public void onConfigured(CameraCaptureSession cameraCaptureSession) { + // The camera is already closed + if (null == mCameraDevice) { + return; + } + // When the session is ready, we start displaying the preview. + cameraCaptureSessions = cameraCaptureSession; + updatePreview(); + } + + @Override + public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) { + mCameraBase.closeCamera(); + Toast.makeText(mActivity, " Preview Configuration change", + Toast.LENGTH_SHORT) + .show(); + } + }, null); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + private void startRecorder(CamcorderProfile mProfile) + throws IOException, CameraAccessException { + closePreviewSession(); + + SurfaceTexture texture = mTextureView.getSurfaceTexture(); + if (texture == null) return; + + if (mProfile.videoFrameWidth == 1280 || mProfile.videoFrameHeight == 720) { + previewSize = SIZE_720P; + + } else if (mProfile.videoFrameWidth == 640 || mProfile.videoFrameHeight == 320) { + previewSize = SIZE_480P; + } + + Log.i(TAG, + "Video previewSize " + previewSize.getWidth() + " x " + previewSize.getHeight()); + + texture.setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight()); + + adjustAspectRatio(previewSize.getWidth(), previewSize.getHeight()); + + captureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_RECORD); + List surfaces = new ArrayList<>(); + + // Set up Surface for the camera preview + Surface previewSurface = new Surface(texture); + surfaces.add(previewSurface); + captureRequestBuilder.addTarget(previewSurface); + + // Set up Surface for the MediaRecorder + Surface recorderSurface = mMediaRecorder.getSurface(); + surfaces.add(recorderSurface); + captureRequestBuilder.addTarget(recorderSurface); + + // Start a capture session + // Once the session starts, we can update the UI and start recording + mCameraDevice.createCaptureSession(surfaces, new CameraCaptureSession.StateCallback() { + @Override + public void onConfigured(@NonNull CameraCaptureSession camCaptureSession) { + cameraCaptureSessions = camCaptureSession; + updatePreview(); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + // UI + mIsRecordingVideo = true; + + // Start recording + + mMediaRecorder.start(); + Log.i(TAG, "MediaRecorder recording.... "); + + mRecordingStartTime = SystemClock.uptimeMillis(); + + updateRecordingTime(); + } + }); + } + + @Override + public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) { + if (null != mActivity) { + Log.e(TAG, "Recording Failed"); + Toast.makeText(mActivity, "Recording Failed", Toast.LENGTH_SHORT).show(); + } + + releaseMedia(); + } + }, mBackgroundHandler); + } + + + public void closePreviewSession() { + if (cameraCaptureSessions != null) { + cameraCaptureSessions.close(); + cameraCaptureSessions = null; + } + } + + + private void updateRecordingTime() { + if (!mIsRecordingVideo) { + return; + } + long now = SystemClock.uptimeMillis(); + long delta = now - mRecordingStartTime; + long mMaxVideoDurationInMs; + mMaxVideoDurationInMs = Utils.getMaxVideoDuration(mActivity); + + // Starting a minute before reaching the max duration + // limit, we'll countdown the remaining time instead. + boolean countdownRemainingTime = + (mMaxVideoDurationInMs != 0 && delta >= mMaxVideoDurationInMs - 60000); + + long deltaAdjusted = delta; + if (countdownRemainingTime) { + deltaAdjusted = Math.max(0, mMaxVideoDurationInMs - deltaAdjusted) + 999; + } + String text; + + long targetNextUpdateDelay; + + text = Utils.millisecondToTimeString(deltaAdjusted, false); + targetNextUpdateDelay = 1000; + + setRecordingTime(text); + + if (mRecordingTimeCountsDown != countdownRemainingTime) { + // Avoid setting the color on every update, do it only + // when it needs changing. + mRecordingTimeCountsDown = countdownRemainingTime; + + int color = mActivity.getResources().getColor(R.color.recording_time_remaining_text); + + setRecordingTimeTextColor(color); + } + + long actualNextUpdateDelay = targetNextUpdateDelay - (delta % targetNextUpdateDelay); + mHandler.sendEmptyMessageDelayed(MSG_UPDATE_RECORD_TIME, actualNextUpdateDelay); + } + + + private void setRecordingTime(String text) { + mRecordingTimeView.setText(text); + } + + public void setRecordingViewTime(TextView RecordingTimeView) { + + mRecordingTimeView = RecordingTimeView; + } + + private void setRecordingTimeTextColor(int color) { + mRecordingTimeView.setTextColor(color); + } + + public void showRecordingUI(boolean recording) { + if (recording) { + mRecordingTimeView.setText(""); + mRecordingTimeView.setVisibility(View.VISIBLE); + mRecordingTimeView.announceForAccessibility( + mActivity.getResources().getString(R.string.video_recording_started)); + + } else { + mRecordingTimeView.announceForAccessibility( + mActivity.getResources().getString(R.string.video_recording_stopped)); + mRecordingTimeView.setVisibility(View.GONE); + } + } + + private void setUpMediaRecorder(CamcorderProfile mProfile) throws IOException { + if (null == mActivity) { + return; + } + String[] VideofileDetails; + + mMediaRecorder = new MediaRecorder(); + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER); + mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); + + { + Context mContext = mActivity.getApplicationContext(); + AudioManager mAudioManager = + (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE); + AudioDeviceInfo[] deviceList = + mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS); + for (AudioDeviceInfo audioDeviceInfo : deviceList) { + if (audioDeviceInfo.getType() == AudioDeviceInfo.TYPE_USB_DEVICE) { + mMediaRecorder.setPreferredDevice(audioDeviceInfo); + break; + } + } + } + + VideofileDetails = Utils.generateFileDetails(Utils.MEDIA_TYPE_VIDEO); + if (VideofileDetails == null || VideofileDetails.length < 5) { + Log.e(TAG, "setUpMediaRecorder Invalid file details"); + return; + } + + mCurrentVideoValues = + Utils.getContentValues(Utils.MEDIA_TYPE_VIDEO, VideofileDetails, + mProfile.videoFrameWidth, mProfile.videoFrameHeight, 0, 0); + + mVideoFilename = VideofileDetails[3]; + + mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + /** + * set output file in media recorder + */ + mMediaRecorder.setOutputFile(mVideoFilename); + + mMediaRecorder.setVideoEncodingBitRate(10000000); + + mMediaRecorder.setVideoFrameRate(mProfile.videoFrameRate); + + Log.i(TAG, "MediaRecorder VideoSize " + mProfile.videoFrameWidth + " x " + + mProfile.videoFrameHeight); + + mMediaRecorder.setVideoSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight); + mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264); + mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + + int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + CameraManager manager = (CameraManager)mActivity.getSystemService(Context.CAMERA_SERVICE); + try { + CameraCharacteristics characteristics = manager.getCameraCharacteristics(mCameraId); + mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION); + } catch (Exception e) { + + } + switch (mSensorOrientation) { + case SENSOR_ORIENTATION_DEFAULT_DEGREES: + mMediaRecorder.setOrientationHint(DEFAULT_ORIENTATIONS.get(rotation)); + break; + case SENSOR_ORIENTATION_INVERSE_DEGREES: + mMediaRecorder.setOrientationHint(INVERSE_ORIENTATIONS.get(rotation)); + break; + } + + // Set maximum file size. + long maxFileSize = + MultiViewActivity.getStorageSpaceBytes() - Utils.LOW_STORAGE_THRESHOLD_BYTES; + Log.d(TAG, "maximum file size is" + maxFileSize); + Toast.makeText(mActivity, "maxFileSize is " + maxFileSize, Toast.LENGTH_SHORT).show(); + try { + mMediaRecorder.setMaxFileSize(maxFileSize); + } catch (RuntimeException exception) { + // We are going to ignore failure of setMaxFileSize here, as + // a) The composer selected may simply not support it, or + // b) The underlying media framework may not handle 64-bit range + // on the size restriction. + } + + try { + mMediaRecorder.prepare(); + } catch (IOException ex) { + Log.e(TAG, "MediaRecorder prepare failed for " + mVideoFilename, ex); + releaseMedia(); + throw new RuntimeException(ex); + } + + mMediaRecorder.setOnErrorListener(this); + mMediaRecorder.setOnInfoListener(this); + } + + + /** + * Sets the TextureView transform to preserve the aspect ratio of the video. + */ + private void adjustAspectRatio(int videoWidth, int videoHeight) { + float megaPixels = previewSize.getWidth() * previewSize.getHeight() / 1000000f; + int numerator = SettingsPrefUtil.aspectRatioNumerator(previewSize); + int denominator = SettingsPrefUtil.aspectRatioDenominator(previewSize); + String AspectRatio = + mActivity.getString(R.string.metadata_dimensions_format, previewSize.getWidth(), + previewSize.getHeight(), megaPixels, numerator, denominator); + Log.i(TAG, "AspectRatio is " + AspectRatio); + + if (videoWidth >= 1280 || videoHeight >= 720) { + configureTransform(mTextureView.getWidth(), mTextureView.getHeight()); + return; + } + + int viewWidth = mTextureView.getWidth(); + int viewHeight = mTextureView.getHeight(); + double aspectRatio = (double)videoHeight / videoWidth; + + int newWidth, newHeight; + if (viewHeight > (int)(viewWidth * aspectRatio)) { + // limited by narrow width; restrict height + newWidth = viewWidth; + newHeight = (int)(viewWidth * aspectRatio); + } else { + // limited by short height; restrict width + newWidth = (int)(viewHeight / aspectRatio); + newHeight = viewHeight; + } + int xoff = (viewWidth - newWidth) / 2; + int yoff = (viewHeight - newHeight) / 2; + Log.v(TAG, "video=" + videoWidth + "x" + videoHeight + " view=" + viewWidth + "x" + + viewHeight + " newView=" + newWidth + "x" + newHeight + " off=" + xoff + + "," + yoff); + + Matrix txform = new Matrix(); + mTextureView.getTransform(txform); + txform.setScale((float)newWidth / viewWidth, (float)newHeight / viewHeight); + // txform.postRotate(10); // just for fun + txform.postTranslate(xoff, yoff); + mTextureView.setTransform(txform); + } + + private CamcorderProfile getSelectedCamorderProfile() { + CamcorderProfile mProfile; + + settings = PreferenceManager.getDefaultSharedPreferences(mActivity); + String videoQuality = settings.getString(mVideoKey, SIZE_HD); + + int quality = SettingsPrefUtil.getFromSetting(videoQuality); + + Log.i(TAG, "Selected video quality " + videoQuality); + + mProfile = CamcorderProfile.get(0, quality); + + return mProfile; + } + + + public void releaseMedia() { + if (null != mMediaRecorder) { + try { + mMediaRecorder.setOnErrorListener(null); + mMediaRecorder.setOnInfoListener(null); + mMediaRecorder.stop(); + Log.i(TAG, "MediaRecorder stop "); + + } catch (IllegalStateException e) { + Log.e(TAG, "stop fail", e); + if (mVideoFilename != null) { + deleteVideoFile(mVideoFilename); + } + } + mMediaRecorder.reset(); + mMediaRecorder.release(); + mMediaRecorder = null; + } + } + + + private void deleteVideoFile(String fileName) { + Log.v(TAG, "Deleting video " + fileName); + File f = new File(fileName); + if (!f.delete()) { + Log.e(TAG, "Could not delete " + fileName); + } + } + + + private void updatePreview() { + if (null == mCameraDevice) { + Log.e(TAG, "updatePreview error"); + } + captureRequestBuilder.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO); + HandlerThread thread = new HandlerThread("Camera Preview"); + thread.start(); + Handler handler = new Handler(thread.getLooper()); + try { + cameraCaptureSessions.setRepeatingRequest(captureRequestBuilder.build(), null, handler); + } catch (CameraAccessException e) { + e.printStackTrace(); + } + } + + + private void configureTransform(int viewWidth, int viewHeight) { + if (null == mTextureView || null == previewSize) { + return; + } + int rotation = mActivity.getWindowManager().getDefaultDisplay().getRotation(); + Matrix matrix = new Matrix(); + RectF viewRect = new RectF(0, 0, viewWidth, viewHeight); + Log.v(TAG, "configureTransform() viewWidth: " + viewWidth + " viewHeight: " + viewHeight + + "previewWidth: " + previewSize.getWidth() + + "previewHeight:" + previewSize.getHeight()); + + RectF bufferRect = new RectF(0, 0, previewSize.getHeight(), previewSize.getWidth()); + float centerX = viewRect.centerX(); + float centerY = viewRect.centerY(); + if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) { + bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY()); + matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL); + float scale = Math.max((float)viewHeight / previewSize.getHeight(), + (float)viewWidth / previewSize.getWidth()); + matrix.postScale(scale, scale, centerX, centerY); + matrix.postRotate(90 * (rotation - 2), centerX, centerY); + } else if (Surface.ROTATION_180 == rotation) { + matrix.postRotate(180, centerX, centerY); + } + mTextureView.setTransform(matrix); + } + + + /** + * This Handler is used to post message back onto the main thread of the + * application. + */ + private class MainHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_RECORD_TIME: { + updateRecordingTime(); + break; + } + + default: + Log.v(TAG, "Unhandled message: " + msg.what); + break; + } + } + } + + + private String GetChnagedPrefKey() { + String Key = null; + + switch (mSettingsKey) { + case "pref_resolution": + Key = getString(mSettingsKey, "capture_list"); + break; + case "pref_resolution_1": + Key = getString(mSettingsKey, "capture_list_1"); + break; + case "pref_resolution_2": + Key = getString(mSettingsKey, "capture_list_2"); + break; + case "pref_resolution_3": + Key = getString(mSettingsKey, "capture_list_3"); + break; + default: + break; + } + + return Key; + } + + + /** + * Retrieve a setting's value as a String, manually specifiying + * a default value. + */ + private String getString(String key, String defaultValue) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mActivity); + try { + return preferences.getString(key, defaultValue); + } catch (ClassCastException e) { + Log.w(TAG, "existing preference with invalid type,removing and returning default", e); + preferences.edit().remove(key).apply(); + return defaultValue; + } + } + + private void saveVideo() { + long duration = SystemClock.uptimeMillis() - mRecordingStartTime; + Log.w(TAG, "Video duration <= 0 : " + duration); + Uri uri; + + mCurrentVideoValues.put(MediaStore.Video.Media.DURATION, duration); + mCurrentVideoValues.put(MediaStore.Video.Media.SIZE, new File(mVideoFilename).length()); + + uri = Utils.broadcastNewVideo(mActivity.getApplicationContext(), mCurrentVideoValues); + + ic_camera.setCurrentUri(uri); + + ic_camera.setCurrentFileInfo(mCurrentVideoValues); + + Log.i(TAG, "video saved @: " + mVideoFilename); + + mVideoFilename = null; + } + + void setCameraDevice(CameraDevice cameraDevice) { + mCameraDevice = cameraDevice; + } +} diff --git a/camera/MultiCameraApplication/res/drawable/camera_switch.png b/camera/MultiCameraApplication/res/drawable/camera_switch.png new file mode 100644 index 0000000..f675aca Binary files /dev/null and b/camera/MultiCameraApplication/res/drawable/camera_switch.png differ diff --git a/camera/MultiCameraApplication/res/drawable/ic_camera_switch.png b/camera/MultiCameraApplication/res/drawable/ic_camera_switch.png new file mode 100644 index 0000000..f180dc9 Binary files /dev/null and b/camera/MultiCameraApplication/res/drawable/ic_camera_switch.png differ diff --git a/camera/MultiCameraApplication/res/drawable/ic_wall_moun_camera.png b/camera/MultiCameraApplication/res/drawable/ic_wall_moun_camera.png new file mode 100644 index 0000000..ef3044f Binary files /dev/null and b/camera/MultiCameraApplication/res/drawable/ic_wall_moun_camera.png differ diff --git a/camera/MultiCameraApplication/res/layout/activity_full_screen.xml b/camera/MultiCameraApplication/res/layout/activity_full_screen.xml new file mode 100644 index 0000000..ebcc9d4 --- /dev/null +++ b/camera/MultiCameraApplication/res/layout/activity_full_screen.xml @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/camera/MultiCameraApplication/res/layout/activity_photo_preview.xml b/camera/MultiCameraApplication/res/layout/activity_photo_preview.xml new file mode 100644 index 0000000..3c61107 --- /dev/null +++ b/camera/MultiCameraApplication/res/layout/activity_photo_preview.xml @@ -0,0 +1,9 @@ + + + + diff --git a/camera/MultiCameraApplication/res/layout/activity_video_record.xml b/camera/MultiCameraApplication/res/layout/activity_video_record.xml new file mode 100644 index 0000000..c9c7612 --- /dev/null +++ b/camera/MultiCameraApplication/res/layout/activity_video_record.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/camera/MultiCameraApplication/res/layout/botmleftcam.xml b/camera/MultiCameraApplication/res/layout/botmleftcam.xml index bc24fe1..9122cdf 100644 --- a/camera/MultiCameraApplication/res/layout/botmleftcam.xml +++ b/camera/MultiCameraApplication/res/layout/botmleftcam.xml @@ -69,12 +69,23 @@ android:gravity="bottom|center" android:orientation="horizontal"> + + @@ -84,8 +95,19 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="15dp" + android:visibility="gone" android:background="@drawable/photo_selector" app:srcCompat="@drawable/ic_capture_camera_normal" /> + + + + @@ -85,8 +96,20 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="15dp" + android:visibility="gone" android:background="@drawable/photo_selector" app:srcCompat="@drawable/ic_capture_camera_normal" /> + + + + tools:showIn="@layout/activity_multiview"> - + @@ -85,10 +95,20 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="15dp" + android:visibility="gone" android:background="@drawable/photo_selector" android:src="@drawable/ic_capture_camera_normal" android:clickable="true"/> + diff --git a/camera/MultiCameraApplication/res/layout/toprightcam.xml b/camera/MultiCameraApplication/res/layout/toprightcam.xml index 6498df8..2848020 100644 --- a/camera/MultiCameraApplication/res/layout/toprightcam.xml +++ b/camera/MultiCameraApplication/res/layout/toprightcam.xml @@ -15,7 +15,7 @@ android:layout_height="match_parent" /> - + android:visibility="gone" + /> + + @@ -83,8 +95,20 @@ android:layout_height="wrap_content" android:layout_gravity="bottom|end" android:layout_margin="15dp" + android:visibility="gone" android:background="@drawable/photo_selector" android:src="@drawable/ic_capture_camera_normal" /> + + +