CameraDeviceCompat.java
/*
* Copyright 2019 The Android Open Source Project
*
* 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 androidx.camera.camera2.impl.compat;
import android.annotation.TargetApi;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraDevice;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
import androidx.camera.camera2.impl.compat.params.SessionConfigurationCompat;
import java.util.concurrent.Executor;
/**
* Helper for accessing features in {@link CameraDevice} in a backwards compatible fashion.
*/
@TargetApi(21)
public final class CameraDeviceCompat {
/**
* Standard camera operation mode.
*
* @hide
*/
@RestrictTo(Scope.LIBRARY)
public static final int SESSION_OPERATION_MODE_NORMAL =
0; // ICameraDeviceUser.NORMAL_MODE;
/**
* Constrained high-speed operation mode.
*
* @hide
*/
@RestrictTo(Scope.LIBRARY)
public static final int SESSION_OPERATION_MODE_CONSTRAINED_HIGH_SPEED =
1; // ICameraDeviceUser.CONSTRAINED_HIGH_SPEED_MODE;
private static final CameraDeviceCompatImpl IMPL = chooseImplementation();
// Class is not a wrapper. Should not be instantiated.
private CameraDeviceCompat() {
}
/**
* Create a new {@link CameraCaptureSession} using a {@link SessionConfigurationCompat}
* helper object that aggregates all supported parameters.
*
* @param device The {@link CameraDevice} used to create the capture session.
* @param config A session configuration (see {@link SessionConfigurationCompat}).
* @throws IllegalArgumentException In case the session configuration
* is invalid; or the output configurations are empty; or
* the session configuration executor is invalid.
* @throws CameraAccessException In case the camera device is no longer connected or has
* encountered a fatal error.
*/
public static void createCaptureSession(@NonNull CameraDevice device,
@NonNull SessionConfigurationCompat config) throws CameraAccessException {
IMPL.createCaptureSession(device, config);
}
private static CameraDeviceCompatImpl chooseImplementation() {
if (Build.VERSION.SDK_INT >= 28) {
return new CameraDeviceCompatApi28Impl();
} else if (Build.VERSION.SDK_INT >= 24) {
return new CameraDeviceCompatApi24Impl();
} else if (Build.VERSION.SDK_INT >= 23) {
return new CameraDeviceCompatApi23Impl();
}
return new CameraDeviceCompatBaseImpl();
}
interface CameraDeviceCompatImpl {
void createCaptureSession(@NonNull CameraDevice device,
@NonNull SessionConfigurationCompat config) throws CameraAccessException;
}
static final class StateCallbackExecutorWrapper extends CameraDevice.StateCallback {
final CameraDevice.StateCallback mWrappedCallback;
private final Executor mExecutor;
StateCallbackExecutorWrapper(@NonNull Executor executor,
@NonNull CameraDevice.StateCallback wrappedCallback) {
mExecutor = executor;
mWrappedCallback = wrappedCallback;
}
@Override
public void onOpened(@NonNull final CameraDevice camera) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mWrappedCallback.onOpened(camera);
}
});
}
@Override
public void onDisconnected(@NonNull final CameraDevice camera) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mWrappedCallback.onDisconnected(camera);
}
});
}
@Override
public void onError(@NonNull final CameraDevice camera, final int error) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mWrappedCallback.onError(camera, error);
}
});
}
@Override
public void onClosed(@NonNull final CameraDevice camera) {
mExecutor.execute(new Runnable() {
@Override
public void run() {
mWrappedCallback.onClosed(camera);
}
});
}
}
}