@@ -305,6 +305,7 @@ public void onSurfaceDestroyed() {
305305 boolean start () {
306306 if (!chooseCameraIdByFacing ()) {
307307 mAspectRatio = mInitialRatio ;
308+ mCallback .onMountError ();
308309 return false ;
309310 }
310311 collectCameraInfo ();
@@ -731,6 +732,33 @@ void setDeviceOrientation(int deviceOrientation) {
731732 //mPreview.setDisplayOrientation(deviceOrientation); // this is not needed and messes up the display orientation
732733 }
733734
735+
736+ // This is a helper method to query Camera2 legacy status so we don't need
737+ // to instantiate and set all its props in order to check if it is legacy or not
738+ // and then fallback to Camera1. This way, legacy devices can fall back to Camera1 right away
739+ // This method makes sure all cameras are not legacy, so further checks are not needed.
740+ public static boolean isLegacy (Context context ){
741+ try {
742+ CameraManager manager = (CameraManager ) context .getSystemService (Context .CAMERA_SERVICE );
743+ String [] ids = manager .getCameraIdList ();
744+ for (String id : ids ) {
745+ CameraCharacteristics characteristics = manager .getCameraCharacteristics (id );
746+ Integer level = characteristics .get (
747+ CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL );
748+ if (level == null ||
749+ level == CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ) {
750+ Log .w (TAG , "Camera2 can only run in legacy mode and should not be used." );
751+ return true ;
752+ }
753+ }
754+ return false ;
755+ }
756+ catch (CameraAccessException ex ){
757+ Log .e (TAG , "Failed to check camera legacy status, returning true." , ex );
758+ return true ;
759+ }
760+ }
761+
734762 /**
735763 * <p>Chooses a camera ID by the specified camera facing ({@link #mFacing}).</p>
736764 * <p>This rewrites {@link #mCameraId}, {@link #mCameraCharacteristics}, and optionally
@@ -742,19 +770,16 @@ private boolean chooseCameraIdByFacing() {
742770 int internalFacing = INTERNAL_FACINGS .get (mFacing );
743771 final String [] ids = mCameraManager .getCameraIdList ();
744772 if (ids .length == 0 ) { // No camera
745- throw new RuntimeException ("No camera available." );
773+ Log .e (TAG , "No cameras available." );
774+ return false ;
746775 }
747776 for (String id : ids ) {
748777 CameraCharacteristics characteristics = mCameraManager .getCameraCharacteristics (id );
749- Integer level = characteristics .get (
750- CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL );
751- if (level == null ||
752- level == CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ) {
753- continue ;
754- }
778+
755779 Integer internal = characteristics .get (CameraCharacteristics .LENS_FACING );
756780 if (internal == null ) {
757- throw new NullPointerException ("Unexpected state: LENS_FACING null" );
781+ Log .e (TAG , "Unexpected state: LENS_FACING null" );
782+ continue ;
758783 }
759784 if (internal == internalFacing ) {
760785 mCameraId = id ;
@@ -765,15 +790,11 @@ private boolean chooseCameraIdByFacing() {
765790 // Not found
766791 mCameraId = ids [0 ];
767792 mCameraCharacteristics = mCameraManager .getCameraCharacteristics (mCameraId );
768- Integer level = mCameraCharacteristics .get (
769- CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL );
770- if (level == null ||
771- level == CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ) {
772- return false ;
773- }
793+
774794 Integer internal = mCameraCharacteristics .get (CameraCharacteristics .LENS_FACING );
775795 if (internal == null ) {
776- throw new NullPointerException ("Unexpected state: LENS_FACING null" );
796+ Log .e (TAG , "Unexpected state: LENS_FACING null" );
797+ return false ;
777798 }
778799 for (int i = 0 , count = INTERNAL_FACINGS .size (); i < count ; i ++) {
779800 if (INTERNAL_FACINGS .valueAt (i ) == internal ) {
@@ -786,7 +807,8 @@ private boolean chooseCameraIdByFacing() {
786807 mFacing = Constants .FACING_BACK ;
787808 return true ;
788809 } catch (CameraAccessException e ) {
789- throw new RuntimeException ("Failed to get a list of camera devices" , e );
810+ Log .e (TAG , "Failed to get a list of camera devices" , e );
811+ return false ;
790812 }
791813 }
792814 else {
@@ -796,17 +818,11 @@ private boolean chooseCameraIdByFacing() {
796818 // for legacy hardware
797819 mCameraCharacteristics = mCameraManager .getCameraCharacteristics (_mCameraId );
798820
799- Integer level = mCameraCharacteristics .get (
800- CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL );
801- if (level == null ||
802- level == CameraCharacteristics .INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ) {
803- return false ;
804- }
805-
806821 // set our facing variable so orientation also works as expected
807822 Integer internal = mCameraCharacteristics .get (CameraCharacteristics .LENS_FACING );
808823 if (internal == null ) {
809- throw new NullPointerException ("Unexpected state: LENS_FACING null" );
824+ Log .e (TAG , "Unexpected state: LENS_FACING null" );
825+ return false ;
810826 }
811827 for (int i = 0 , count = INTERNAL_FACINGS .size (); i < count ; i ++) {
812828 if (INTERNAL_FACINGS .valueAt (i ) == internal ) {
@@ -819,7 +835,8 @@ private boolean chooseCameraIdByFacing() {
819835 return true ;
820836 }
821837 catch (Exception e ){
822- throw new RuntimeException ("Failed to get camera characteristics" , e );
838+ Log .e (TAG , "Failed to get camera characteristics" , e );
839+ return false ;
823840 }
824841 }
825842 }
0 commit comments