Merge "Camera: Keep sensor orientation consistent with device fold state" into sc-v2-dev
This commit is contained in:
@@ -17949,6 +17949,7 @@ package android.hardware.camera2 {
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.hardware.camera2.params.DeviceStateOrientationMap> INFO_DEVICE_STATE_ORIENTATION_MAP;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> INFO_SUPPORTED_HARDWARE_LEVEL;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.String> INFO_VERSION;
|
||||
field @NonNull public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Size[]> JPEG_AVAILABLE_THUMBNAIL_SIZES;
|
||||
@@ -18643,6 +18644,12 @@ package android.hardware.camera2.params {
|
||||
method public android.util.Rational getElement(int, int);
|
||||
}
|
||||
|
||||
public final class DeviceStateOrientationMap {
|
||||
method public int getSensorOrientation(long);
|
||||
field public static final long FOLDED = 4L; // 0x4L
|
||||
field public static final long NORMAL = 0L; // 0x0L
|
||||
}
|
||||
|
||||
public final class ExtensionSessionConfiguration {
|
||||
ctor public ExtensionSessionConfiguration(int, @NonNull java.util.List<android.hardware.camera2.params.OutputConfiguration>, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraExtensionSession.StateCallback);
|
||||
method @NonNull public java.util.concurrent.Executor getExecutor();
|
||||
|
||||
@@ -22,15 +22,18 @@ import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.hardware.camera2.impl.CameraMetadataNative;
|
||||
import android.hardware.camera2.impl.PublicKey;
|
||||
import android.hardware.camera2.impl.SyntheticKey;
|
||||
import android.hardware.camera2.params.DeviceStateOrientationMap;
|
||||
import android.hardware.camera2.params.RecommendedStreamConfigurationMap;
|
||||
import android.hardware.camera2.params.SessionConfiguration;
|
||||
import android.hardware.camera2.utils.TypeReference;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
import android.util.Rational;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -202,8 +205,25 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
private List<CaptureResult.Key<?>> mAvailableResultKeys;
|
||||
private ArrayList<RecommendedStreamConfigurationMap> mRecommendedConfigurations;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
@GuardedBy("mLock")
|
||||
private boolean mFoldedDeviceState;
|
||||
|
||||
private final CameraManager.DeviceStateListener mFoldStateListener =
|
||||
new CameraManager.DeviceStateListener() {
|
||||
@Override
|
||||
public final void onDeviceStateChanged(boolean folded) {
|
||||
synchronized (mLock) {
|
||||
mFoldedDeviceState = folded;
|
||||
}
|
||||
}};
|
||||
|
||||
private static final String TAG = "CameraCharacteristics";
|
||||
|
||||
/**
|
||||
* Takes ownership of the passed-in properties object
|
||||
*
|
||||
* @param properties Camera properties.
|
||||
* @hide
|
||||
*/
|
||||
public CameraCharacteristics(CameraMetadataNative properties) {
|
||||
@@ -219,6 +239,41 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
return new CameraMetadataNative(mProperties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the device state listener for this Camera characteristics instance
|
||||
*/
|
||||
CameraManager.DeviceStateListener getDeviceStateListener() { return mFoldStateListener; }
|
||||
|
||||
/**
|
||||
* Overrides the property value
|
||||
*
|
||||
* <p>Check whether a given property value needs to be overridden in some specific
|
||||
* case.</p>
|
||||
*
|
||||
* @param key The characteristics field to override.
|
||||
* @return The value of overridden property, or {@code null} if the property doesn't need an
|
||||
* override.
|
||||
*/
|
||||
@Nullable
|
||||
private <T> T overrideProperty(Key<T> key) {
|
||||
if (CameraCharacteristics.SENSOR_ORIENTATION.equals(key) && (mFoldStateListener != null) &&
|
||||
(mProperties.get(CameraCharacteristics.INFO_DEVICE_STATE_ORIENTATIONS) != null)) {
|
||||
DeviceStateOrientationMap deviceStateOrientationMap =
|
||||
mProperties.get(CameraCharacteristics.INFO_DEVICE_STATE_ORIENTATION_MAP);
|
||||
synchronized (mLock) {
|
||||
Integer ret = deviceStateOrientationMap.getSensorOrientation(mFoldedDeviceState ?
|
||||
DeviceStateOrientationMap.FOLDED : DeviceStateOrientationMap.NORMAL);
|
||||
if (ret >= 0) {
|
||||
return (T) ret;
|
||||
} else {
|
||||
Log.w(TAG, "No valid device state to orientation mapping! Using default!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a camera characteristics field value.
|
||||
*
|
||||
@@ -235,7 +290,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
*/
|
||||
@Nullable
|
||||
public <T> T get(Key<T> key) {
|
||||
return mProperties.get(key);
|
||||
T propertyOverride = overrideProperty(key);
|
||||
return (propertyOverride != null) ? propertyOverride : mProperties.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3993,11 +4049,26 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
* upright on the device screen in its native orientation.</p>
|
||||
* <p>Also defines the direction of rolling shutter readout, which is from top to bottom in
|
||||
* the sensor's coordinate system.</p>
|
||||
* <p>Starting with Android API level 32, camera clients that query the orientation via
|
||||
* {@link android.hardware.camera2.CameraCharacteristics#get } on foldable devices which
|
||||
* include logical cameras can receive a value that can dynamically change depending on the
|
||||
* device/fold state.
|
||||
* Clients are advised to not cache or store the orientation value of such logical sensors.
|
||||
* In case repeated queries to CameraCharacteristics are not preferred, then clients can
|
||||
* also access the entire mapping from device state to sensor orientation in
|
||||
* {@link android.hardware.camera2.params.DeviceStateOrientationMap }.
|
||||
* Do note that a dynamically changing sensor orientation value in camera characteristics
|
||||
* will not be the best way to establish the orientation per frame. Clients that want to
|
||||
* know the sensor orientation of a particular captured frame should query the
|
||||
* {@link CaptureResult#LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID android.logicalMultiCamera.activePhysicalId} from the corresponding capture result and
|
||||
* check the respective physical camera orientation.</p>
|
||||
* <p><b>Units</b>: Degrees of clockwise rotation; always a multiple of
|
||||
* 90</p>
|
||||
* <p><b>Range of valid values:</b><br>
|
||||
* 0, 90, 180, 270</p>
|
||||
* <p>This key is available on all devices.</p>
|
||||
*
|
||||
* @see CaptureResult#LOGICAL_MULTI_CAMERA_ACTIVE_PHYSICAL_ID
|
||||
*/
|
||||
@PublicKey
|
||||
@NonNull
|
||||
@@ -4306,6 +4377,46 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
|
||||
public static final Key<String> INFO_VERSION =
|
||||
new Key<String>("android.info.version", String.class);
|
||||
|
||||
/**
|
||||
* <p>This lists the mapping between a device folding state and
|
||||
* specific camera sensor orientation for logical cameras on a foldable device.</p>
|
||||
* <p>Logical cameras on foldable devices can support sensors with different orientation
|
||||
* values. The orientation value may need to change depending on the specific folding
|
||||
* state. Information about the mapping between the device folding state and the
|
||||
* sensor orientation can be obtained in
|
||||
* {@link android.hardware.camera2.params.DeviceStateOrientationMap }.
|
||||
* Device state orientation maps are optional and maybe present on devices that support
|
||||
* {@link CaptureRequest#SCALER_ROTATE_AND_CROP android.scaler.rotateAndCrop}.</p>
|
||||
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
|
||||
* <p><b>Limited capability</b> -
|
||||
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
|
||||
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
|
||||
*
|
||||
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
|
||||
* @see CaptureRequest#SCALER_ROTATE_AND_CROP
|
||||
*/
|
||||
@PublicKey
|
||||
@NonNull
|
||||
@SyntheticKey
|
||||
public static final Key<android.hardware.camera2.params.DeviceStateOrientationMap> INFO_DEVICE_STATE_ORIENTATION_MAP =
|
||||
new Key<android.hardware.camera2.params.DeviceStateOrientationMap>("android.info.deviceStateOrientationMap", android.hardware.camera2.params.DeviceStateOrientationMap.class);
|
||||
|
||||
/**
|
||||
* <p>HAL must populate the array with
|
||||
* (hardware::camera::provider::V2_5::DeviceState, sensorOrientation) pairs for each
|
||||
* supported device state bitwise combination.</p>
|
||||
* <p><b>Units</b>: (device fold state, sensor orientation) x n</p>
|
||||
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
|
||||
* <p><b>Limited capability</b> -
|
||||
* Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the
|
||||
* {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p>
|
||||
*
|
||||
* @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL
|
||||
* @hide
|
||||
*/
|
||||
public static final Key<long[]> INFO_DEVICE_STATE_ORIENTATIONS =
|
||||
new Key<long[]>("android.info.deviceStateOrientations", long[].class);
|
||||
|
||||
/**
|
||||
* <p>The maximum number of frames that can occur after a request
|
||||
* (different than the previous) has been submitted, and before the
|
||||
|
||||
@@ -30,15 +30,19 @@ import android.hardware.ICameraServiceListener;
|
||||
import android.hardware.camera2.impl.CameraDeviceImpl;
|
||||
import android.hardware.camera2.impl.CameraInjectionSessionImpl;
|
||||
import android.hardware.camera2.impl.CameraMetadataNative;
|
||||
import android.hardware.camera2.params.DeviceStateOrientationMap;
|
||||
import android.hardware.camera2.params.ExtensionSessionConfiguration;
|
||||
import android.hardware.camera2.params.SessionConfiguration;
|
||||
import android.hardware.camera2.params.StreamConfiguration;
|
||||
import android.hardware.camera2.utils.CameraIdAndSessionConfiguration;
|
||||
import android.hardware.camera2.utils.ConcurrentCameraIdCombination;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.hardware.display.DisplayManager;
|
||||
import android.os.Binder;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerExecutor;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
@@ -50,6 +54,10 @@ import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.view.Display;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
@@ -97,6 +105,80 @@ public final class CameraManager {
|
||||
synchronized(mLock) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
mHandlerThread = new HandlerThread(TAG);
|
||||
mHandlerThread.start();
|
||||
mHandler = new Handler(mHandlerThread.getLooper());
|
||||
mFoldStateListener = new FoldStateListener(context);
|
||||
context.getSystemService(DeviceStateManager.class)
|
||||
.registerCallback(new HandlerExecutor(mHandler), mFoldStateListener);
|
||||
}
|
||||
|
||||
private HandlerThread mHandlerThread;
|
||||
private Handler mHandler;
|
||||
private FoldStateListener mFoldStateListener;
|
||||
@GuardedBy("mLock")
|
||||
private ArrayList<WeakReference<DeviceStateListener>> mDeviceStateListeners = new ArrayList<>();
|
||||
private boolean mFoldedDeviceState;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public interface DeviceStateListener {
|
||||
void onDeviceStateChanged(boolean folded);
|
||||
}
|
||||
|
||||
private final class FoldStateListener implements DeviceStateManager.DeviceStateCallback {
|
||||
private final int[] mFoldedDeviceStates;
|
||||
|
||||
public FoldStateListener(Context context) {
|
||||
mFoldedDeviceStates = context.getResources().getIntArray(
|
||||
com.android.internal.R.array.config_foldedDeviceStates);
|
||||
}
|
||||
|
||||
private void handleStateChange(int state) {
|
||||
boolean folded = ArrayUtils.contains(mFoldedDeviceStates, state);
|
||||
synchronized (mLock) {
|
||||
mFoldedDeviceState = folded;
|
||||
ArrayList<WeakReference<DeviceStateListener>> invalidListeners = new ArrayList<>();
|
||||
for (WeakReference<DeviceStateListener> listener : mDeviceStateListeners) {
|
||||
DeviceStateListener callback = listener.get();
|
||||
if (callback != null) {
|
||||
callback.onDeviceStateChanged(folded);
|
||||
} else {
|
||||
invalidListeners.add(listener);
|
||||
}
|
||||
}
|
||||
if (!invalidListeners.isEmpty()) {
|
||||
mDeviceStateListeners.removeAll(invalidListeners);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onBaseStateChanged(int state) {
|
||||
handleStateChange(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void onStateChanged(int state) {
|
||||
handleStateChange(state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link CameraCharacteristics} device state listener
|
||||
*
|
||||
* @param chars Camera characteristics that need to receive device state updates
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void registerDeviceStateListener(@NonNull CameraCharacteristics chars) {
|
||||
synchronized (mLock) {
|
||||
DeviceStateListener listener = chars.getDeviceStateListener();
|
||||
listener.onDeviceStateChanged(mFoldedDeviceState);
|
||||
mDeviceStateListeners.add(new WeakReference<>(listener));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -504,6 +586,7 @@ public final class CameraManager {
|
||||
"Camera service is currently unavailable", e);
|
||||
}
|
||||
}
|
||||
registerDeviceStateListener(characteristics);
|
||||
return characteristics;
|
||||
}
|
||||
|
||||
@@ -1327,8 +1410,7 @@ public final class CameraManager {
|
||||
private ICameraService mCameraService;
|
||||
|
||||
// Singleton, don't allow construction
|
||||
private CameraManagerGlobal() {
|
||||
}
|
||||
private CameraManagerGlobal() { }
|
||||
|
||||
public static final boolean sCameraServiceDisabled =
|
||||
SystemProperties.getBoolean("config.disable_cameraservice", false);
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfiguration
|
||||
import android.hardware.camera2.marshal.impl.MarshalQueryableStreamConfigurationDuration;
|
||||
import android.hardware.camera2.marshal.impl.MarshalQueryableString;
|
||||
import android.hardware.camera2.params.Capability;
|
||||
import android.hardware.camera2.params.DeviceStateOrientationMap;
|
||||
import android.hardware.camera2.params.Face;
|
||||
import android.hardware.camera2.params.HighSpeedVideoConfiguration;
|
||||
import android.hardware.camera2.params.LensShadingMap;
|
||||
@@ -754,13 +755,22 @@ public class CameraMetadataNative implements Parcelable {
|
||||
});
|
||||
sGetCommandMap.put(
|
||||
CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP.getNativeKey(),
|
||||
new GetCommand() {
|
||||
new GetCommand() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
|
||||
return (T) metadata.getLensShadingMap();
|
||||
}
|
||||
});
|
||||
sGetCommandMap.put(
|
||||
CameraCharacteristics.INFO_DEVICE_STATE_ORIENTATION_MAP.getNativeKey(),
|
||||
new GetCommand() {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getValue(CameraMetadataNative metadata, Key<T> key) {
|
||||
return (T) metadata.getDeviceStateOrientationMap();
|
||||
}
|
||||
});
|
||||
sGetCommandMap.put(
|
||||
CaptureResult.STATISTICS_OIS_SAMPLES.getNativeKey(),
|
||||
new GetCommand() {
|
||||
@@ -994,6 +1004,18 @@ public class CameraMetadataNative implements Parcelable {
|
||||
return map;
|
||||
}
|
||||
|
||||
private DeviceStateOrientationMap getDeviceStateOrientationMap() {
|
||||
long[] mapArray = getBase(CameraCharacteristics.INFO_DEVICE_STATE_ORIENTATIONS);
|
||||
|
||||
// Do not warn if map is null while s is not. This is valid.
|
||||
if (mapArray == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DeviceStateOrientationMap map = new DeviceStateOrientationMap(mapArray);
|
||||
return map;
|
||||
}
|
||||
|
||||
private Location getGpsLocation() {
|
||||
String processingMethod = get(CaptureResult.JPEG_GPS_PROCESSING_METHOD);
|
||||
double[] coords = get(CaptureResult.JPEG_GPS_COORDINATES);
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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 android.hardware.camera2.params;
|
||||
|
||||
import android.annotation.LongDef;
|
||||
import android.hardware.camera2.CameraCharacteristics;
|
||||
import android.hardware.camera2.utils.HashCodeHelpers;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Immutable class that maps the device fold state to sensor orientation.
|
||||
*
|
||||
* <p>Some {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA logical}
|
||||
* cameras on foldables can include physical sensors with different sensor orientation
|
||||
* values. As a result, the values of the logical camera device can potentially change depending
|
||||
* on the device fold state.</p>
|
||||
*
|
||||
* <p>The device fold state to sensor orientation map will contain information about the
|
||||
* respective logical camera sensor orientation given a device state. Clients
|
||||
* can query the mapping for all possible supported folded states.
|
||||
*
|
||||
* @see CameraCharacteristics#SENSOR_ORIENTATION
|
||||
*/
|
||||
public final class DeviceStateOrientationMap {
|
||||
/**
|
||||
* Needs to be kept in sync with the HIDL/AIDL DeviceState
|
||||
*/
|
||||
|
||||
/**
|
||||
* The device is in its normal physical configuration. This is the default if the
|
||||
* device does not support multiple different states.
|
||||
*/
|
||||
public static final long NORMAL = 0;
|
||||
|
||||
/**
|
||||
* The device is folded. If not set, the device is unfolded or does not
|
||||
* support folding.
|
||||
*
|
||||
* The exact point when this status change happens during the folding
|
||||
* operation is device-specific.
|
||||
*/
|
||||
public static final long FOLDED = 1 << 2;
|
||||
|
||||
/** @hide */
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@LongDef(prefix = {"DEVICE_STATE"}, value =
|
||||
{NORMAL,
|
||||
FOLDED })
|
||||
public @interface DeviceState {};
|
||||
|
||||
private final HashMap<Long, Integer> mDeviceStateOrientationMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Create a new immutable DeviceStateOrientationMap instance.
|
||||
*
|
||||
* <p>This constructor takes over the array; do not write to the array afterwards.</p>
|
||||
*
|
||||
* @param elements
|
||||
* An array of elements describing the map
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the {@code elements} array length is invalid, not divisible by 2 or contains
|
||||
* invalid element values
|
||||
* @throws NullPointerException
|
||||
* if {@code elements} is {@code null}
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public DeviceStateOrientationMap(final long[] elements) {
|
||||
mElements = Objects.requireNonNull(elements, "elements must not be null");
|
||||
if ((elements.length % 2) != 0) {
|
||||
throw new IllegalArgumentException("Device state orientation map length " +
|
||||
elements.length + " is not even!");
|
||||
}
|
||||
|
||||
for (int i = 0; i < elements.length; i += 2) {
|
||||
if ((elements[i+1] % 90) != 0) {
|
||||
throw new IllegalArgumentException("Sensor orientation not divisible by 90: " +
|
||||
elements[i+1]);
|
||||
}
|
||||
|
||||
mDeviceStateOrientationMap.put(elements[i], Math.toIntExact(elements[i + 1]));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the logical camera sensor orientation given a specific device fold state.
|
||||
*
|
||||
* @param deviceState Device fold state
|
||||
*
|
||||
* @return Valid {@link android.hardware.camera2.CameraCharacteristics#SENSOR_ORIENTATION} for
|
||||
* any supported device fold state
|
||||
*
|
||||
* @throws IllegalArgumentException if the given device state is invalid
|
||||
*/
|
||||
public int getSensorOrientation(@DeviceState long deviceState) {
|
||||
if (!mDeviceStateOrientationMap.containsKey(deviceState)) {
|
||||
throw new IllegalArgumentException("Invalid device state: " + deviceState);
|
||||
}
|
||||
|
||||
return mDeviceStateOrientationMap.get(deviceState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this DeviceStateOrientationMap is equal to another DeviceStateOrientationMap.
|
||||
*
|
||||
* <p>Two device state orientation maps are equal if and only if all of their elements are
|
||||
* {@link Object#equals equal}.</p>
|
||||
*
|
||||
* @return {@code true} if the objects were equal, {@code false} otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof DeviceStateOrientationMap) {
|
||||
final DeviceStateOrientationMap other = (DeviceStateOrientationMap) obj;
|
||||
return Arrays.equals(mElements, other.mElements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return HashCodeHelpers.hashCodeGeneric(mElements);
|
||||
}
|
||||
|
||||
private final long[] mElements;
|
||||
}
|
||||
@@ -19,6 +19,7 @@ import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Camera;
|
||||
import android.graphics.GraphicBuffer;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.camera2.CameraAccessException;
|
||||
@@ -135,6 +136,7 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
private HashMap<String, CameraCharacteristics> mCharacteristicsHashMap = new HashMap<>();
|
||||
private HashMap<String, Long> mMetadataVendorIdMap = new HashMap<>();
|
||||
private CameraManager mCameraManager;
|
||||
|
||||
private static boolean checkForAdvancedAPI() {
|
||||
if (EXTENSIONS_PRESENT && EXTENSIONS_VERSION.startsWith(ADVANCED_VERSION_PREFIX)) {
|
||||
@@ -460,12 +462,12 @@ public class CameraExtensionsProxyService extends Service {
|
||||
// This will setup the camera vendor tag descriptor in the service process
|
||||
// along with all camera characteristics.
|
||||
try {
|
||||
CameraManager manager = getSystemService(CameraManager.class);
|
||||
mCameraManager = getSystemService(CameraManager.class);
|
||||
|
||||
String [] cameraIds = manager.getCameraIdListNoLazy();
|
||||
String [] cameraIds = mCameraManager.getCameraIdListNoLazy();
|
||||
if (cameraIds != null) {
|
||||
for (String cameraId : cameraIds) {
|
||||
CameraCharacteristics chars = manager.getCameraCharacteristics(cameraId);
|
||||
CameraCharacteristics chars = mCameraManager.getCameraCharacteristics(cameraId);
|
||||
mCharacteristicsHashMap.put(cameraId, chars);
|
||||
Object thisClass = CameraCharacteristics.Key.class;
|
||||
Class<CameraCharacteristics.Key<?>> keyClass =
|
||||
@@ -1174,8 +1176,9 @@ public class CameraExtensionsProxyService extends Service {
|
||||
@Override
|
||||
public void onInit(String cameraId, CameraMetadataNative cameraCharacteristics) {
|
||||
mCameraId = cameraId;
|
||||
mPreviewExtender.onInit(cameraId, new CameraCharacteristics(cameraCharacteristics),
|
||||
CameraExtensionsProxyService.this);
|
||||
CameraCharacteristics chars = new CameraCharacteristics(cameraCharacteristics);
|
||||
mCameraManager.registerDeviceStateListener(chars);
|
||||
mPreviewExtender.onInit(cameraId, chars, CameraExtensionsProxyService.this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1200,13 +1203,16 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
@Override
|
||||
public void init(String cameraId, CameraMetadataNative chars) {
|
||||
mPreviewExtender.init(cameraId, new CameraCharacteristics(chars));
|
||||
CameraCharacteristics c = new CameraCharacteristics(chars);
|
||||
mCameraManager.registerDeviceStateListener(c);
|
||||
mPreviewExtender.init(cameraId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExtensionAvailable(String cameraId, CameraMetadataNative chars) {
|
||||
return mPreviewExtender.isExtensionAvailable(cameraId,
|
||||
new CameraCharacteristics(chars));
|
||||
CameraCharacteristics c = new CameraCharacteristics(chars);
|
||||
mCameraManager.registerDeviceStateListener(c);
|
||||
return mPreviewExtender.isExtensionAvailable(cameraId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1283,8 +1289,9 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
@Override
|
||||
public void onInit(String cameraId, CameraMetadataNative cameraCharacteristics) {
|
||||
mImageExtender.onInit(cameraId, new CameraCharacteristics(cameraCharacteristics),
|
||||
CameraExtensionsProxyService.this);
|
||||
CameraCharacteristics chars = new CameraCharacteristics(cameraCharacteristics);
|
||||
mCameraManager.registerDeviceStateListener(chars);
|
||||
mImageExtender.onInit(cameraId, chars, CameraExtensionsProxyService.this);
|
||||
mCameraId = cameraId;
|
||||
}
|
||||
|
||||
@@ -1310,13 +1317,16 @@ public class CameraExtensionsProxyService extends Service {
|
||||
|
||||
@Override
|
||||
public void init(String cameraId, CameraMetadataNative chars) {
|
||||
mImageExtender.init(cameraId, new CameraCharacteristics(chars));
|
||||
CameraCharacteristics c = new CameraCharacteristics(chars);
|
||||
mCameraManager.registerDeviceStateListener(c);
|
||||
mImageExtender.init(cameraId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExtensionAvailable(String cameraId, CameraMetadataNative chars) {
|
||||
return mImageExtender.isExtensionAvailable(cameraId,
|
||||
new CameraCharacteristics(chars));
|
||||
CameraCharacteristics c = new CameraCharacteristics(chars);
|
||||
mCameraManager.registerDeviceStateListener(c);
|
||||
return mImageExtender.isExtensionAvailable(cameraId, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user