Camera: Torch strength control API.

This change contains below new public APIs:
1. Change the torch strength level.
2. Get the torch brightness level.
3. Callback when torch strength level is changed.

Bug: 200174275

Test: atest -c cts/tests/camera on aosp_cf_x86_64_phone-userdebug
Change-Id: I8b2d3a7dd9114986d3171832744a3dd6db092a48
This commit is contained in:
Rucha Katakwar
2021-11-10 11:32:09 -08:00
parent 4109534bb3
commit 748da4343c
3 changed files with 206 additions and 0 deletions

View File

@@ -18482,6 +18482,7 @@ package android.hardware.camera2 {
method @NonNull public android.hardware.camera2.CameraExtensionCharacteristics getCameraExtensionCharacteristics(@NonNull String) throws android.hardware.camera2.CameraAccessException;
method @NonNull public String[] getCameraIdList() throws android.hardware.camera2.CameraAccessException;
method @NonNull public java.util.Set<java.util.Set<java.lang.String>> getConcurrentCameraIds() throws android.hardware.camera2.CameraAccessException;
method public int getTorchStrengthLevel(@NonNull String) throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(android.Manifest.permission.CAMERA) public boolean isConcurrentSessionConfigurationSupported(@NonNull java.util.Map<java.lang.String,android.hardware.camera2.params.SessionConfiguration>) throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(android.Manifest.permission.CAMERA) public void openCamera(@NonNull String, @NonNull android.hardware.camera2.CameraDevice.StateCallback, @Nullable android.os.Handler) throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(android.Manifest.permission.CAMERA) public void openCamera(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
@@ -18490,6 +18491,7 @@ package android.hardware.camera2 {
method public void registerTorchCallback(@NonNull android.hardware.camera2.CameraManager.TorchCallback, @Nullable android.os.Handler);
method public void registerTorchCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraManager.TorchCallback);
method public void setTorchMode(@NonNull String, boolean) throws android.hardware.camera2.CameraAccessException;
method public void turnOnTorchWithStrengthLevel(@NonNull String, int) throws android.hardware.camera2.CameraAccessException;
method public void unregisterAvailabilityCallback(@NonNull android.hardware.camera2.CameraManager.AvailabilityCallback);
method public void unregisterTorchCallback(@NonNull android.hardware.camera2.CameraManager.TorchCallback);
}
@@ -18507,6 +18509,7 @@ package android.hardware.camera2 {
ctor public CameraManager.TorchCallback();
method public void onTorchModeChanged(@NonNull String, boolean);
method public void onTorchModeUnavailable(@NonNull String);
method public void onTorchStrengthLevelChanged(@NonNull String, int);
}
public abstract class CameraMetadata<TKey> {

View File

@@ -1035,6 +1035,95 @@ public final class CameraManager {
CameraManagerGlobal.get().setTorchMode(cameraId, enabled);
}
/**
* Set the brightness level of the flashlight associated with the given cameraId in torch
* mode. If the torch is OFF and torchStrength is >= 1, torch will turn ON with the
* strength level specified in torchStrength.
*
* <p>Use
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_MAXIMUM_LEVEL}
* to check whether the camera device supports flash unit strength control or not. If this value
* is greater than 1, applications can call this API to control the flashlight brightness level.
* </p>
*
* <p>If {@link #turnOnTorchWithStrengthLevel} is called to change the brightness level of the
* flash unit {@link CameraManager.TorchCallback#onTorchStrengthLevelChanged} will be invoked.
* If the new desired strength level is same as previously set level, then this callback will
* not be invoked.
* If the torch is OFF and {@link #turnOnTorchWithStrengthLevel} is called with level >= 1,
* the torch will be turned ON with that brightness level. In this case
* {@link CameraManager.TorchCallback#onTorchModeChanged} will also be invoked.
* </p>
*
* <p>When the torch is turned OFF via {@link #setTorchMode}, the flashlight brightness level
* will reset to default value
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_DEFAULT_LEVEL}
* In this case the {@link CameraManager.TorchCallback#onTorchStrengthLevelChanged} will not be
* invoked.
* </p>
*
* <p>If torch is enabled via {@link #setTorchMode} after calling
* {@link #turnOnTorchWithStrengthLevel} with level N then the flash unit will have the
* brightness level N.
* Since multiple applications are free to call {@link #setTorchMode}, when the latest
* application that turned ON the torch mode exits, the torch mode will be turned OFF
* and in this case the brightness level will reset to default level.
* </p>
*
* @param cameraId
* The unique identifier of the camera device that the flash unit belongs to.
* @param torchStrength
* The desired brightness level to be set for the flash unit in the range 1 to
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_MAXIMUM_LEVEL}.
*
* @throws CameraAccessException if it failed to access the flash unit.
* {@link CameraAccessException#CAMERA_IN_USE} will be thrown if the camera device
* is in use. {@link CameraAccessException#MAX_CAMERAS_IN_USE} will be thrown if
* other camera resources needed to turn on the torch mode are in use.
* {@link CameraAccessException#CAMERA_DISCONNECTED} will be thrown if camera
* service is not available.
* @throws IllegalArgumentException if cameraId was null, cameraId doesn't match any currently
* or previously available camera device, the camera device doesn't have a
* flash unit or if torchStrength is not within the range i.e. is greater than
* the maximum level
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_MAXIMUM_LEVEL}
* or <= 0.
*
*/
public void turnOnTorchWithStrengthLevel(@NonNull String cameraId, int torchStrength)
throws CameraAccessException {
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No camera available on device");
}
CameraManagerGlobal.get().turnOnTorchWithStrengthLevel(cameraId, torchStrength);
}
/**
* Returns the brightness level of the flash unit associated with the cameraId.
*
* @param cameraId
* The unique identifier of the camera device that the flash unit belongs to.
* @return The brightness level of the flash unit associated with cameraId.
* When the torch is turned OFF, the strength level will reset to a default level
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_DEFAULT_LEVEL}.
* In this case the return value will be
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_DEFAULT_LEVEL}
* rather than 0.
*
* @throws CameraAccessException if it failed to access the flash unit.
* @throws IllegalArgumentException if cameraId was null, cameraId doesn't match any currently
* or previously available camera device, or the camera device doesn't have a
* flash unit.
*
*/
public int getTorchStrengthLevel(@NonNull String cameraId)
throws CameraAccessException {
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No camera available on device.");
}
return CameraManagerGlobal.get().getTorchStrengthLevel(cameraId);
}
/**
* A callback for camera devices becoming available or unavailable to open.
*
@@ -1239,6 +1328,24 @@ public final class CameraManager {
public void onTorchModeChanged(@NonNull String cameraId, boolean enabled) {
// default empty implementation
}
/**
* A camera's flash unit brightness level has been changed in torch mode via
* {@link #turnOnTorchWithStrengthLevel}. When the torch is turned OFF, this
* callback will not be triggered even though the torch strength level resets to
* default value
* {@link android.hardware.camera2.CameraCharacteristics#FLASH_INFO_STRENGTH_DEFAULT_LEVEL}
*
* <p>The default implementation of this method does nothing.</p>
*
* @param cameraId The unique identifier of the camera whose flash unit brightness level has
* been changed.
*
* @param newStrengthLevel The brightness level of the flash unit that has been changed to.
*/
public void onTorchStrengthLevelChanged(@NonNull String cameraId, int newStrengthLevel) {
// default empty implementation
}
}
/**
@@ -1642,6 +1749,10 @@ public final class CameraManager {
public void onTorchStatusChanged(int status, String id) throws RemoteException {
}
@Override
public void onTorchStrengthLevelChanged(String id, int newStrengthLevel)
throws RemoteException {
}
@Override
public void onCameraAccessPrioritiesChanged() {
}
@Override
@@ -1825,6 +1936,57 @@ public final class CameraManager {
}
}
public void turnOnTorchWithStrengthLevel(String cameraId, int torchStrength) throws
CameraAccessException {
synchronized(mLock) {
if (cameraId == null) {
throw new IllegalArgumentException("cameraId was null");
}
ICameraService cameraService = getCameraService();
if (cameraService == null) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable.");
}
try {
cameraService.turnOnTorchWithStrengthLevel(cameraId, torchStrength,
mTorchClientBinder);
} catch(ServiceSpecificException e) {
throwAsPublicException(e);
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable.");
}
}
}
public int getTorchStrengthLevel(String cameraId) throws CameraAccessException {
int torchStrength = 0;
synchronized(mLock) {
if (cameraId == null) {
throw new IllegalArgumentException("cameraId was null");
}
ICameraService cameraService = getCameraService();
if (cameraService == null) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable.");
}
try {
torchStrength = cameraService.getTorchStrengthLevel(cameraId);
} catch(ServiceSpecificException e) {
throwAsPublicException(e);
} catch (RemoteException e) {
throw new CameraAccessException(CameraAccessException.CAMERA_DISCONNECTED,
"Camera service is currently unavailable.");
}
}
return torchStrength;
}
private void handleRecoverableSetupErrors(ServiceSpecificException e) {
switch (e.errorCode) {
case ICameraService.ERROR_DISCONNECTED:
@@ -1984,6 +2146,18 @@ public final class CameraManager {
}
}
private void postSingleTorchStrengthLevelUpdate(final TorchCallback callback,
final Executor executor, final String id, final int newStrengthLevel) {
final long ident = Binder.clearCallingIdentity();
try {
executor.execute(() -> {
callback.onTorchStrengthLevelChanged(id, newStrengthLevel);
});
} finally {
Binder.restoreCallingIdentity(ident);
}
}
/**
* Send the state of all known cameras to the provided listener, to initialize
* the listener's knowledge of camera state.
@@ -2167,6 +2341,22 @@ public final class CameraManager {
}
} // onTorchStatusChangedLocked
private void onTorchStrengthLevelChangedLocked(String cameraId, int newStrengthLevel) {
if (DEBUG) {
Log.v(TAG,
String.format("Camera id %s has torch strength level changed to %d",
cameraId, newStrengthLevel));
}
final int callbackCount = mTorchCallbackMap.size();
for (int i = 0; i < callbackCount; i++) {
final Executor executor = mTorchCallbackMap.valueAt(i);
final TorchCallback callback = mTorchCallbackMap.keyAt(i);
postSingleTorchStrengthLevelUpdate(callback, executor, cameraId, newStrengthLevel);
}
} // onTorchStrengthLevelChanged
/**
* Register a callback to be notified about camera device availability with the
* global listener singleton.
@@ -2257,6 +2447,14 @@ public final class CameraManager {
}
}
@Override
public void onTorchStrengthLevelChanged(String cameraId, int newStrengthLevel)
throws RemoteException {
synchronized (mLock) {
onTorchStrengthLevelChangedLocked(cameraId, newStrengthLevel);
}
}
@Override
public void onCameraAccessPrioritiesChanged() {
synchronized (mLock) {

View File

@@ -303,6 +303,11 @@ public class CameraBinderTest extends AndroidTestCase {
public void onCameraClosed(String cameraId) {
Log.v(TAG, String.format("Camera %s is closed", cameraId));
}
@Override
public void onTorchStrengthLevelChanged(String cameraId, int torchStrength) {
Log.v(TAG, String.format("Camera " + cameraId + " torch strength level changed to "
+ torchStrength ));
}
}
/**