| Index: webrtc/api/androidtests/src/org/webrtc/Camera2CapturerTest.java
 | 
| diff --git a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java b/webrtc/api/androidtests/src/org/webrtc/Camera2CapturerTest.java
 | 
| similarity index 60%
 | 
| copy from webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java
 | 
| copy to webrtc/api/androidtests/src/org/webrtc/Camera2CapturerTest.java
 | 
| index 614105cd5df6fbc4392a96106b547f2d52568a7e..7ad60c05e7b53d38fa3c9c742a66c540f85d6d91 100644
 | 
| --- a/webrtc/api/androidtests/src/org/webrtc/Camera1CapturerUsingTextureTest.java
 | 
| +++ b/webrtc/api/androidtests/src/org/webrtc/Camera2CapturerTest.java
 | 
| @@ -13,19 +13,143 @@ package org.webrtc;
 | 
|  import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
 | 
|  
 | 
|  import android.content.Context;
 | 
| +import android.hardware.camera2.CameraDevice;
 | 
| +import android.hardware.camera2.CameraManager;
 | 
| +import android.hardware.camera2.CameraAccessException;
 | 
| +import android.os.Handler;
 | 
| +import android.os.Looper;
 | 
|  import android.test.InstrumentationTestCase;
 | 
|  import android.test.suitebuilder.annotation.SmallTest;
 | 
|  import android.test.suitebuilder.annotation.MediumTest;
 | 
|  import android.test.suitebuilder.annotation.LargeTest;
 | 
|  
 | 
| -public class Camera1CapturerUsingTextureTest extends InstrumentationTestCase {
 | 
| -  static final String TAG = "Camera1CapturerUsingTextureTest";
 | 
| +import java.util.concurrent.CountDownLatch;
 | 
| +
 | 
| +public class Camera2CapturerTest extends InstrumentationTestCase {
 | 
| +  static final String TAG = "Camera2CapturerTest";
 | 
| +
 | 
| +  /**
 | 
| +   * Simple camera2 implementation that only knows how to open the camera and close it.
 | 
| +   */
 | 
| +  private class SimpleCamera2 {
 | 
| +    final CameraManager cameraManager;
 | 
| +    final LooperThread looperThread;
 | 
| +    final CountDownLatch openDoneSignal;
 | 
| +    final Object cameraDeviceLock;
 | 
| +    CameraDevice cameraDevice; // Guarded by cameraDeviceLock
 | 
| +    boolean openSucceeded; // Guarded by cameraDeviceLock
 | 
| +
 | 
| +    private class LooperThread extends Thread {
 | 
| +      final CountDownLatch startedSignal = new CountDownLatch(1);
 | 
| +      private Handler handler;
 | 
| +
 | 
| +      @Override
 | 
| +      public void run() {
 | 
| +        Looper.prepare();
 | 
| +        handler = new Handler();
 | 
| +        startedSignal.countDown();
 | 
| +        Looper.loop();
 | 
| +      }
 | 
| +
 | 
| +      public void waitToStart() {
 | 
| +        ThreadUtils.awaitUninterruptibly(startedSignal);
 | 
| +      }
 | 
| +
 | 
| +      public void requestStop() {
 | 
| +        handler.getLooper().quit();
 | 
| +      }
 | 
| +
 | 
| +      public Handler getHandler() {
 | 
| +        return handler;
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +    private class CameraStateCallback extends CameraDevice.StateCallback {
 | 
| +      @Override
 | 
| +      public void onClosed(CameraDevice cameraDevice) {
 | 
| +        Logging.d(TAG, "Simple camera2 closed.");
 | 
| +
 | 
| +        synchronized (cameraDeviceLock) {
 | 
| +          SimpleCamera2.this.cameraDevice = null;
 | 
| +        }
 | 
| +      }
 | 
| +
 | 
| +      @Override
 | 
| +      public void onDisconnected(CameraDevice cameraDevice) {
 | 
| +        Logging.d(TAG, "Simple camera2 disconnected.");
 | 
| +
 | 
| +        synchronized (cameraDeviceLock) {
 | 
| +          SimpleCamera2.this.cameraDevice = null;
 | 
| +        }
 | 
| +      }
 | 
| +
 | 
| +      @Override
 | 
| +      public void onError(CameraDevice cameraDevice, int errorCode) {
 | 
| +        Logging.w(TAG, "Simple camera2 error: " + errorCode);
 | 
| +
 | 
| +        synchronized (cameraDeviceLock) {
 | 
| +          SimpleCamera2.this.cameraDevice = cameraDevice;
 | 
| +          openSucceeded = false;
 | 
| +        }
 | 
| +
 | 
| +        openDoneSignal.countDown();
 | 
| +      }
 | 
| +
 | 
| +      @Override
 | 
| +      public void onOpened(CameraDevice cameraDevice) {
 | 
| +        Logging.d(TAG, "Simple camera2 opened.");
 | 
| +
 | 
| +        synchronized (cameraDeviceLock) {
 | 
| +          SimpleCamera2.this.cameraDevice = cameraDevice;
 | 
| +          openSucceeded = true;
 | 
| +        }
 | 
| +
 | 
| +        openDoneSignal.countDown();
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +    SimpleCamera2(Context context, String deviceName) {
 | 
| +      cameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
 | 
| +      looperThread = new LooperThread();
 | 
| +      looperThread.start();
 | 
| +      looperThread.waitToStart();
 | 
| +      cameraDeviceLock = new Object();
 | 
| +      openDoneSignal = new CountDownLatch(1);
 | 
| +      cameraDevice = null;
 | 
| +      Logging.d(TAG, "Opening simple camera2.");
 | 
| +      try {
 | 
| +        cameraManager.openCamera(deviceName, new CameraStateCallback(), looperThread.getHandler());
 | 
| +      } catch (CameraAccessException e) {
 | 
| +        fail("Simple camera2 CameraAccessException: " + e.getMessage());
 | 
| +      }
 | 
| +
 | 
| +      Logging.d(TAG, "Waiting for simple camera2 to open.");
 | 
| +      ThreadUtils.awaitUninterruptibly(openDoneSignal);
 | 
| +      synchronized (cameraDeviceLock) {
 | 
| +        if (!openSucceeded) {
 | 
| +          fail("Opening simple camera2 failed.");
 | 
| +        }
 | 
| +      }
 | 
| +    }
 | 
| +
 | 
| +    public void close() {
 | 
| +      Logging.d(TAG, "Closing simple camera2.");
 | 
| +      synchronized (cameraDeviceLock) {
 | 
| +        if (cameraDevice != null) {
 | 
| +          cameraDevice.close();
 | 
| +        }
 | 
| +      }
 | 
| +
 | 
| +      looperThread.requestStop();
 | 
| +      ThreadUtils.joinUninterruptibly(looperThread);
 | 
| +    }
 | 
| +  }
 | 
|  
 | 
|    private class TestObjectFactory
 | 
|        extends CameraVideoCapturerTestFixtures.TestObjectFactory {
 | 
|      @Override
 | 
|      public CameraEnumerator getCameraEnumerator() {
 | 
| -      return new Camera1Enumerator();
 | 
| +      return new Camera2Enumerator(getAppContext());
 | 
|      }
 | 
|  
 | 
|      @Override
 | 
| @@ -36,13 +160,13 @@ public class Camera1CapturerUsingTextureTest extends InstrumentationTestCase {
 | 
|      @SuppressWarnings("deprecation")
 | 
|      @Override
 | 
|      public Object rawOpenCamera(String cameraName) {
 | 
| -      return android.hardware.Camera.open(Camera1Enumerator.getCameraIndex(cameraName));
 | 
| +      return new SimpleCamera2(getAppContext(), cameraName);
 | 
|      }
 | 
|  
 | 
|      @SuppressWarnings("deprecation")
 | 
|      @Override
 | 
|      public void rawCloseCamera(Object camera) {
 | 
| -      ((android.hardware.Camera) camera).release();
 | 
| +      ((SimpleCamera2) camera).close();
 | 
|      }
 | 
|    }
 | 
|  
 | 
| 
 |