Move Camera1 specific methods to Camera1Enumerator and create CameraEnumerator interface.

The plan is to use CameraEnumerator as a "factory" for camera objects in
the future. This CL prepares for that by moving Camera1 specific stuff
away from CameraEnumerationAndroid to Camera1Enumerator. Because
CameraEnumerationAndroid methods were part of public API there are
deprecated mocks for now.

When making these changes, I noticed that code duplication in
CameraVideoCapturer tests implementing TestObjectFactory could be
decreased by making TestObjectFactory an abstract class that uses
CameraEnumerator.

BUG=webrtc:5519

Review-Url: https://codereview.webrtc.org/2071803002
Cr-Commit-Position: refs/heads/master@{#13185}
diff --git a/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java b/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java
new file mode 100644
index 0000000..13a5237
--- /dev/null
+++ b/webrtc/api/java/android/org/webrtc/Camera1Enumerator.java
@@ -0,0 +1,159 @@
+/*
+ *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+package org.webrtc;
+
+import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
+
+import android.os.SystemClock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@SuppressWarnings("deprecation")
+public class Camera1Enumerator implements CameraEnumerator {
+  private final static String TAG = "Camera1Enumerator";
+  // Each entry contains the supported formats for corresponding camera index. The formats for all
+  // cameras are enumerated on the first call to getSupportedFormats(), and cached for future
+  // reference.
+  private static List<List<CaptureFormat>> cachedSupportedFormats;
+
+
+  public boolean isFrontFacing(String deviceName) {
+    android.hardware.Camera.CameraInfo info = getCameraInfo(getCameraIndex(deviceName));
+    return info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT;
+  }
+
+  public boolean isBackFacing(String deviceName) {
+    android.hardware.Camera.CameraInfo info = getCameraInfo(getCameraIndex(deviceName));
+    return info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK;
+  }
+
+  public CameraVideoCapturer createCapturer(String deviceName,
+      CameraVideoCapturer.CameraEventsHandler eventsHandler) {
+    return new VideoCapturerAndroid(deviceName, eventsHandler, true);
+  }
+
+  private static android.hardware.Camera.CameraInfo getCameraInfo(int index) {
+    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
+    try {
+      android.hardware.Camera.getCameraInfo(index, info);
+    } catch (Exception e) {
+      Logging.e(TAG, "getCameraInfo failed on index " + index,e);
+      return null;
+    }
+    return info;
+  }
+
+  static synchronized List<CaptureFormat> getSupportedFormats(int cameraId) {
+    if (cachedSupportedFormats == null) {
+      cachedSupportedFormats = new ArrayList<List<CaptureFormat>>();
+      for (int i = 0; i < CameraEnumerationAndroid.getDeviceCount(); ++i) {
+        cachedSupportedFormats.add(enumerateFormats(i));
+      }
+    }
+    return cachedSupportedFormats.get(cameraId);
+  }
+
+  private static List<CaptureFormat> enumerateFormats(int cameraId) {
+    Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".");
+    final long startTimeMs = SystemClock.elapsedRealtime();
+    final android.hardware.Camera.Parameters parameters;
+    android.hardware.Camera camera = null;
+    try {
+      Logging.d(TAG, "Opening camera with index " + cameraId);
+      camera = android.hardware.Camera.open(cameraId);
+      parameters = camera.getParameters();
+    } catch (RuntimeException e) {
+      Logging.e(TAG, "Open camera failed on camera index " + cameraId, e);
+      return new ArrayList<CaptureFormat>();
+    } finally {
+      if (camera != null) {
+        camera.release();
+      }
+    }
+
+    final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
+    try {
+      int minFps = 0;
+      int maxFps = 0;
+      final List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
+      if (listFpsRange != null) {
+        // getSupportedPreviewFpsRange() returns a sorted list. Take the fps range
+        // corresponding to the highest fps.
+        final int[] range = listFpsRange.get(listFpsRange.size() - 1);
+        minFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
+        maxFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
+      }
+      for (android.hardware.Camera.Size size : parameters.getSupportedPreviewSizes()) {
+        formatList.add(new CaptureFormat(size.width, size.height, minFps, maxFps));
+      }
+    } catch (Exception e) {
+      Logging.e(TAG, "getSupportedFormats() failed on camera index " + cameraId, e);
+    }
+
+    final long endTimeMs = SystemClock.elapsedRealtime();
+    Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done."
+        + " Time spent: " + (endTimeMs - startTimeMs) + " ms.");
+    return formatList;
+  }
+
+  // Convert from android.hardware.Camera.Size to Size.
+  public static List<Size> convertSizes(List<android.hardware.Camera.Size> cameraSizes) {
+    final List<Size> sizes = new ArrayList<Size>();
+    for (android.hardware.Camera.Size size : cameraSizes) {
+      sizes.add(new Size(size.width, size.height));
+    }
+    return sizes;
+  }
+
+  // Convert from int[2] to CaptureFormat.FramerateRange.
+  public static List<CaptureFormat.FramerateRange> convertFramerates(List<int[]> arrayRanges) {
+    final List<CaptureFormat.FramerateRange> ranges = new ArrayList<CaptureFormat.FramerateRange>();
+    for (int[] range : arrayRanges) {
+      ranges.add(new CaptureFormat.FramerateRange(
+          range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
+          range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]));
+    }
+    return ranges;
+  }
+
+  // Returns device names that can be used to create a new VideoCapturerAndroid.
+  public String[] getDeviceNames() {
+    String[] names = new String[android.hardware.Camera.getNumberOfCameras()];
+    for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) {
+      names[i] = getDeviceName(i);
+    }
+    return names;
+  }
+
+  // Returns the camera index for camera with name |deviceName|, or throws IllegalArgumentException
+  // if no such camera can be found.
+  static int getCameraIndex(String deviceName) {
+    Logging.d(TAG, "getCameraIndex: " + deviceName);
+    for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) {
+      if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) {
+        return i;
+      }
+    }
+    throw new IllegalArgumentException("No such camera: " + deviceName);
+  }
+
+  // Returns the name of the camera with camera index. Returns null if the
+  // camera can not be used.
+  static String getDeviceName(int index) {
+    android.hardware.Camera.CameraInfo info = getCameraInfo(index);
+
+    String facing =
+        (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) ? "front" : "back";
+    return "Camera " + index + ", Facing " + facing
+        + ", Orientation " + info.orientation;
+  }
+}
diff --git a/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java b/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java
index f3e08f6..b3c5062 100644
--- a/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java
+++ b/webrtc/api/java/android/org/webrtc/CameraEnumerationAndroid.java
@@ -114,57 +114,48 @@
     }
   }
 
-  // Returns device names that can be used to create a new VideoCapturerAndroid.
+  /**
+   * @deprecated
+   * Please use Camera1Enumerator.getDeviceNames() instead.
+   */
+  @Deprecated
   public static String[] getDeviceNames() {
-    String[] names = new String[android.hardware.Camera.getNumberOfCameras()];
-    for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) {
-      names[i] = getDeviceName(i);
-    }
-    return names;
+    return new Camera1Enumerator().getDeviceNames();
   }
 
-  // Returns number of cameras on device.
+
+  /**
+   * @deprecated
+   * Please use Camera1Enumerator.getDeviceNames().length instead.
+   */
+  @Deprecated
   public static int getDeviceCount() {
-    return android.hardware.Camera.getNumberOfCameras();
+    return new Camera1Enumerator().getDeviceNames().length;
   }
 
-  // Returns the name of the camera with camera index. Returns null if the
-  // camera can not be used.
+  /**
+   * @deprecated
+   * Please use Camera1Enumerator.getDeviceNames().get(index) instead.
+   */
+  @Deprecated
   public static String getDeviceName(int index) {
-    android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
-    try {
-      android.hardware.Camera.getCameraInfo(index, info);
-    } catch (Exception e) {
-      Logging.e(TAG, "getCameraInfo failed on index " + index,e);
-      return null;
-    }
-
-    String facing =
-        (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) ? "front" : "back";
-    return "Camera " + index + ", Facing " + facing
-        + ", Orientation " + info.orientation;
+    return new Camera1Enumerator().getDeviceName(index);
   }
 
-  // Returns the camera index for camera with name |deviceName|, or throws IllegalArgumentException
-  // if no such camera can be found.
-  public static int getCameraIndex(String deviceName) {
-    Logging.d(TAG, "getCameraIndex: " + deviceName);
-    for (int i = 0; i < android.hardware.Camera.getNumberOfCameras(); ++i) {
-      if (deviceName.equals(CameraEnumerationAndroid.getDeviceName(i))) {
-        return i;
-      }
-    }
-    throw new IllegalArgumentException("No such camera: " + deviceName);
-  }
-
-  // Returns the name of the front facing camera. Returns null if the
-  // camera can not be used or does not exist.
+  /**
+   * @deprecated
+   * Please use Camera1Enumerator.isFrontFacing(String deviceName) instead.
+   */
+  @Deprecated
   public static String getNameOfFrontFacingDevice() {
     return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
   }
 
-  // Returns the name of the back facing camera. Returns null if the
-  // camera can not be used or does not exist.
+  /**
+   * @deprecated
+   * Please use Camera1Enumerator.isBackFacing(String deviceName) instead.
+   */
+  @Deprecated
   public static String getNameOfBackFacingDevice() {
     return getNameOfDevice(android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK);
   }
diff --git a/webrtc/api/java/android/org/webrtc/CameraEnumerator.java b/webrtc/api/java/android/org/webrtc/CameraEnumerator.java
index 203c195..752e10a 100644
--- a/webrtc/api/java/android/org/webrtc/CameraEnumerator.java
+++ b/webrtc/api/java/android/org/webrtc/CameraEnumerator.java
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2015 The WebRTC project authors. All Rights Reserved.
+ *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
  *
  *  Use of this source code is governed by a BSD-style license
  *  that can be found in the LICENSE file in the root of the source
@@ -10,94 +10,11 @@
 
 package org.webrtc;
 
-import android.os.SystemClock;
+public interface CameraEnumerator {
+  public String[] getDeviceNames();
+  public boolean isFrontFacing(String deviceName);
+  public boolean isBackFacing(String deviceName);
 
-import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
-import org.webrtc.Logging;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@SuppressWarnings("deprecation")
-public class CameraEnumerator {
-  private final static String TAG = "CameraEnumerator";
-  // Each entry contains the supported formats for corresponding camera index. The formats for all
-  // cameras are enumerated on the first call to getSupportedFormats(), and cached for future
-  // reference.
-  private static List<List<CaptureFormat>> cachedSupportedFormats;
-
-  public static synchronized List<CaptureFormat> getSupportedFormats(int cameraId) {
-    if (cachedSupportedFormats == null) {
-      cachedSupportedFormats = new ArrayList<List<CaptureFormat>>();
-      for (int i = 0; i < CameraEnumerationAndroid.getDeviceCount(); ++i) {
-        cachedSupportedFormats.add(enumerateFormats(i));
-      }
-    }
-    return cachedSupportedFormats.get(cameraId);
-  }
-
-  private static List<CaptureFormat> enumerateFormats(int cameraId) {
-    Logging.d(TAG, "Get supported formats for camera index " + cameraId + ".");
-    final long startTimeMs = SystemClock.elapsedRealtime();
-    final android.hardware.Camera.Parameters parameters;
-    android.hardware.Camera camera = null;
-    try {
-      Logging.d(TAG, "Opening camera with index " + cameraId);
-      camera = android.hardware.Camera.open(cameraId);
-      parameters = camera.getParameters();
-    } catch (RuntimeException e) {
-      Logging.e(TAG, "Open camera failed on camera index " + cameraId, e);
-      return new ArrayList<CaptureFormat>();
-    } finally {
-      if (camera != null) {
-        camera.release();
-      }
-    }
-
-    final List<CaptureFormat> formatList = new ArrayList<CaptureFormat>();
-    try {
-      int minFps = 0;
-      int maxFps = 0;
-      final List<int[]> listFpsRange = parameters.getSupportedPreviewFpsRange();
-      if (listFpsRange != null) {
-        // getSupportedPreviewFpsRange() returns a sorted list. Take the fps range
-        // corresponding to the highest fps.
-        final int[] range = listFpsRange.get(listFpsRange.size() - 1);
-        minFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX];
-        maxFps = range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX];
-      }
-      for (android.hardware.Camera.Size size : parameters.getSupportedPreviewSizes()) {
-        formatList.add(new CaptureFormat(size.width, size.height, minFps, maxFps));
-      }
-    } catch (Exception e) {
-      Logging.e(TAG, "getSupportedFormats() failed on camera index " + cameraId, e);
-    }
-
-    final long endTimeMs = SystemClock.elapsedRealtime();
-    Logging.d(TAG, "Get supported formats for camera index " + cameraId + " done."
-        + " Time spent: " + (endTimeMs - startTimeMs) + " ms.");
-    return formatList;
-  }
-
-  // Convert from android.hardware.Camera.Size to Size.
-  public static List<Size> convertSizes(
-      List<android.hardware.Camera.Size> cameraSizes) {
-    final List<Size> sizes = new ArrayList<Size>();
-    for (android.hardware.Camera.Size size : cameraSizes) {
-      sizes.add(new Size(size.width, size.height));
-    }
-    return sizes;
-  }
-
-  // Convert from int[2] to CaptureFormat.FramerateRange.
-  public static List<CaptureFormat.FramerateRange> convertFramerates(
-      List<int[]> arrayRanges) {
-    final List<CaptureFormat.FramerateRange> ranges = new ArrayList<CaptureFormat.FramerateRange>();
-    for (int[] range : arrayRanges) {
-      ranges.add(new CaptureFormat.FramerateRange(
-          range[android.hardware.Camera.Parameters.PREVIEW_FPS_MIN_INDEX],
-          range[android.hardware.Camera.Parameters.PREVIEW_FPS_MAX_INDEX]));
-    }
-    return ranges;
-  }
+  public CameraVideoCapturer createCapturer(String deviceName,
+      CameraVideoCapturer.CameraEventsHandler eventsHandler);
 }
diff --git a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java
index 5e9a5a6..7e9d019 100644
--- a/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java
+++ b/webrtc/api/java/android/org/webrtc/VideoCapturerAndroid.java
@@ -208,7 +208,7 @@
 
   @Override
   public List<CaptureFormat> getSupportedFormats() {
-    return CameraEnumerator.getSupportedFormats(getCurrentCameraId());
+    return Camera1Enumerator.getSupportedFormats(getCurrentCameraId());
   }
 
   // Returns true if this VideoCapturer is setup to capture video frames to a SurfaceTexture.
@@ -224,7 +224,7 @@
     if (cameraName == null || cameraName.equals("")) {
       this.id = 0;
     } else {
-      this.id = CameraEnumerationAndroid.getCameraIndex(cameraName);
+      this.id = Camera1Enumerator.getCameraIndex(cameraName);
     }
     this.eventsHandler = eventsHandler;
     isCapturingToTexture = captureToTexture;
@@ -391,14 +391,14 @@
     // Find closest supported format for |width| x |height| @ |framerate|.
     final android.hardware.Camera.Parameters parameters = camera.getParameters();
     final List<CaptureFormat.FramerateRange> supportedFramerates =
-        CameraEnumerator.convertFramerates(parameters.getSupportedPreviewFpsRange());
+        Camera1Enumerator.convertFramerates(parameters.getSupportedPreviewFpsRange());
     Logging.d(TAG, "Available fps ranges: " + supportedFramerates);
 
     final CaptureFormat.FramerateRange fpsRange =
         CameraEnumerationAndroid.getClosestSupportedFramerateRange(supportedFramerates, framerate);
 
     final Size previewSize = CameraEnumerationAndroid.getClosestSupportedSize(
-        CameraEnumerator.convertSizes(parameters.getSupportedPreviewSizes()), width, height);
+        Camera1Enumerator.convertSizes(parameters.getSupportedPreviewSizes()), width, height);
 
     final CaptureFormat captureFormat =
         new CaptureFormat(previewSize.width, previewSize.height, fpsRange);
@@ -427,7 +427,7 @@
     // Picture size is for taking pictures and not for preview/video, but we need to set it anyway
     // as a workaround for an aspect ratio problem on Nexus 7.
     final Size pictureSize = CameraEnumerationAndroid.getClosestSupportedSize(
-        CameraEnumerator.convertSizes(parameters.getSupportedPictureSizes()), width, height);
+        Camera1Enumerator.convertSizes(parameters.getSupportedPictureSizes()), width, height);
     parameters.setPictureSize(pictureSize.width, pictureSize.height);
 
     // Temporarily stop preview if it's already running.
diff --git a/webrtc/api/java/jni/classreferenceholder.cc b/webrtc/api/java/jni/classreferenceholder.cc
index 8ed01c5..3d8f304 100644
--- a/webrtc/api/java/jni/classreferenceholder.cc
+++ b/webrtc/api/java/jni/classreferenceholder.cc
@@ -48,7 +48,7 @@
   LoadClass(jni, "java/nio/ByteBuffer");
   LoadClass(jni, "java/util/ArrayList");
   LoadClass(jni, "org/webrtc/AudioTrack");
-  LoadClass(jni, "org/webrtc/CameraEnumerator");
+  LoadClass(jni, "org/webrtc/Camera1Enumerator");
   LoadClass(jni, "org/webrtc/Camera2Enumerator");
   LoadClass(jni, "org/webrtc/CameraEnumerationAndroid");
   LoadClass(jni, "org/webrtc/DataChannel");