Loading core/java/android/hardware/camera2/CameraManager.java +46 −25 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.SystemProperties; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.Size; import android.view.Display; Loading Loading @@ -379,7 +380,8 @@ public final class CameraManager { */ @NonNull public Set<Set<String>> getConcurrentCameraIds() throws CameraAccessException { return CameraManagerGlobal.get().getConcurrentCameraIds(); return CameraManagerGlobal.get().getConcurrentCameraIds(mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); } /** Loading Loading @@ -418,7 +420,8 @@ public final class CameraManager { @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig) throws CameraAccessException { return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported( cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion); cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion, mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); } /** Loading Loading @@ -794,7 +797,7 @@ public final class CameraManager { boolean hasConcurrentStreams = CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId, mContext.getDeviceId()); mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams); Size displaySize = getDisplaySize(); Loading Loading @@ -2097,7 +2100,7 @@ public final class CameraManager { // Opened Camera ID -> apk name map private final ArrayMap<DeviceCameraInfo, String> mOpenedDevices = new ArrayMap<>(); private final Set<Set<String>> mConcurrentCameraIdCombinations = new ArraySet<>(); private final Set<Set<DeviceCameraInfo>> mConcurrentCameraIdCombinations = new ArraySet<>(); // Registered availability callbacks and their executors private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>(); Loading Loading @@ -2256,7 +2259,13 @@ public final class CameraManager { ConcurrentCameraIdCombination[] cameraIdCombinations = cameraService.getConcurrentCameraIds(); for (ConcurrentCameraIdCombination comb : cameraIdCombinations) { mConcurrentCameraIdCombinations.add(comb.getConcurrentCameraIdCombination()); Set<Pair<String, Integer>> combination = comb.getConcurrentCameraIdCombination(); Set<DeviceCameraInfo> deviceCameraInfoSet = new ArraySet<>(); for (Pair<String, Integer> entry : combination) { deviceCameraInfoSet.add(new DeviceCameraInfo(entry.first, entry.second)); } mConcurrentCameraIdCombinations.add(deviceCameraInfoSet); } } catch (ServiceSpecificException e) { // Unexpected failure Loading Loading @@ -2341,13 +2350,12 @@ public final class CameraManager { return cameraIds.toArray(new String[0]); } private Set<Set<String>> extractConcurrentCameraIdListLocked() { private Set<Set<String>> extractConcurrentCameraIdListLocked(int deviceId, int devicePolicy) { Set<Set<String>> concurrentCameraIds = new ArraySet<>(); for (Set<String> cameraIds : mConcurrentCameraIdCombinations) { for (Set<DeviceCameraInfo> deviceCameraInfos : mConcurrentCameraIdCombinations) { Set<String> extractedCameraIds = new ArraySet<>(); for (String cameraId : cameraIds) { // TODO(b/291736219): This to be made device-aware. DeviceCameraInfo info = new DeviceCameraInfo(cameraId, DEVICE_ID_DEFAULT); for (DeviceCameraInfo info : deviceCameraInfos) { // if the camera id status is NOT_PRESENT or ENUMERATING; skip the device. // TODO: Would a device status NOT_PRESENT ever be in the map ? it gets removed // in the callback anyway. Loading @@ -2360,10 +2368,15 @@ public final class CameraManager { || status == ICameraServiceListener.STATUS_NOT_PRESENT) { continue; } extractedCameraIds.add(cameraId); if (shouldHideCamera(deviceId, devicePolicy, info)) { continue; } extractedCameraIds.add(info.mCameraId); } if (!extractedCameraIds.isEmpty()) { concurrentCameraIds.add(extractedCameraIds); } } return concurrentCameraIds; } Loading Loading @@ -2523,12 +2536,13 @@ public final class CameraManager { return cameraIds; } public @NonNull Set<Set<String>> getConcurrentCameraIds() { public @NonNull Set<Set<String>> getConcurrentCameraIds(int deviceId, int devicePolicy) { Set<Set<String>> concurrentStreamingCameraIds; synchronized (mLock) { // Try to make sure we have an up-to-date list of concurrent camera devices. connectCameraServiceLocked(); concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked(); concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked(deviceId, devicePolicy); } // TODO: Some sort of sorting ? return concurrentStreamingCameraIds; Loading @@ -2536,13 +2550,12 @@ public final class CameraManager { public boolean isConcurrentSessionConfigurationSupported( @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations, int targetSdkVersion) throws CameraAccessException { int targetSdkVersion, int deviceId, int devicePolicy) throws CameraAccessException { if (cameraIdsAndSessionConfigurations == null) { throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null"); } // TODO(b/291736219): Check if this API needs to be made device-aware. int size = cameraIdsAndSessionConfigurations.size(); if (size == 0) { throw new IllegalArgumentException("camera id and session combination is empty"); Loading @@ -2552,8 +2565,14 @@ public final class CameraManager { // Go through all the elements and check if the camera ids are valid at least / // belong to one of the combinations returned by getConcurrentCameraIds() boolean subsetFound = false; for (Set<String> combination : mConcurrentCameraIdCombinations) { if (combination.containsAll(cameraIdsAndSessionConfigurations.keySet())) { for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) { Set<DeviceCameraInfo> infos = new ArraySet<>(); for (String cameraId : cameraIdsAndSessionConfigurations.keySet()) { infos.add(new DeviceCameraInfo(cameraId, devicePolicy == DEVICE_POLICY_DEFAULT ? DEVICE_ID_DEFAULT : deviceId)); } if (combination.containsAll(infos)) { subsetFound = true; } } Loading @@ -2573,7 +2592,7 @@ public final class CameraManager { } try { return mCameraService.isConcurrentSessionConfigurationSupported( cameraIdsAndConfigs, targetSdkVersion); cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy); } catch (ServiceSpecificException e) { throw ExceptionUtils.throwAsPublicException(e); } catch (RemoteException e) { Loading @@ -2592,8 +2611,10 @@ public final class CameraManager { * @return Whether the camera device was found in the set of combinations returned by * getConcurrentCameraIds */ public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId) { DeviceCameraInfo info = new DeviceCameraInfo(cameraId, deviceId); public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId, int devicePolicy) { DeviceCameraInfo info = new DeviceCameraInfo(cameraId, devicePolicy == DEVICE_POLICY_DEFAULT ? DEVICE_ID_DEFAULT : deviceId); if (!mDeviceStatus.containsKey(info)) { // physical camera ids aren't advertised in concurrent camera id combinations. if (DEBUG) { Loading @@ -2602,8 +2623,8 @@ public final class CameraManager { } return false; } for (Set<String> comb : mConcurrentCameraIdCombinations) { if (comb.contains(cameraId)) { for (Set<DeviceCameraInfo> comb : mConcurrentCameraIdCombinations) { if (comb.contains(info)) { return true; } } Loading core/java/android/hardware/camera2/utils/ConcurrentCameraIdCombination.java +23 −19 Original line number Diff line number Diff line Loading @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware.camera2.utils; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; import android.util.Pair; import java.util.HashSet; import java.util.Set; /** Loading @@ -30,11 +32,11 @@ import java.util.Set; */ public class ConcurrentCameraIdCombination implements Parcelable { private Set<String> mConcurrentCameraIds = new HashSet<>(); private final Set<Pair<String, Integer>> mConcurrentCameraIdDeviceIdPairs = new ArraySet<>(); public static final @NonNull Parcelable.Creator<ConcurrentCameraIdCombination> CREATOR = new Parcelable.Creator<ConcurrentCameraIdCombination>() { new Parcelable.Creator<>() { @Override public ConcurrentCameraIdCombination createFromParcel(Parcel in) { return new ConcurrentCameraIdCombination(in); Loading @@ -57,9 +59,10 @@ public class ConcurrentCameraIdCombination implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mConcurrentCameraIds.size()); for (String cameraId : mConcurrentCameraIds) { dest.writeString(cameraId); dest.writeInt(mConcurrentCameraIdDeviceIdPairs.size()); for (Pair<String, Integer> cameraIdDeviceIdPair : mConcurrentCameraIdDeviceIdPairs) { dest.writeString(cameraIdDeviceIdPair.first); dest.writeInt(cameraIdDeviceIdPair.second); } } Loading @@ -67,7 +70,7 @@ public class ConcurrentCameraIdCombination implements Parcelable { * helper for CREATOR */ public void readFromParcel(Parcel in) { mConcurrentCameraIds.clear(); mConcurrentCameraIdDeviceIdPairs.clear(); int cameraCombinationSize = in.readInt(); if (cameraCombinationSize < 0) { throw new RuntimeException("cameraCombinationSize " + cameraCombinationSize Loading @@ -78,14 +81,15 @@ public class ConcurrentCameraIdCombination implements Parcelable { if (cameraId == null) { throw new RuntimeException("Failed to read camera id from Parcel"); } mConcurrentCameraIds.add(cameraId); int deviceId = in.readInt(); mConcurrentCameraIdDeviceIdPairs.add(new Pair<>(cameraId, deviceId)); } } /** * Get this concurrent camera id combination. */ public Set<String> getConcurrentCameraIdCombination() { return mConcurrentCameraIds; public Set<Pair<String, Integer>> getConcurrentCameraIdCombination() { return mConcurrentCameraIdDeviceIdPairs; } } Loading
core/java/android/hardware/camera2/CameraManager.java +46 −25 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ import android.os.SystemProperties; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; import android.util.Pair; import android.util.Size; import android.view.Display; Loading Loading @@ -379,7 +380,8 @@ public final class CameraManager { */ @NonNull public Set<Set<String>> getConcurrentCameraIds() throws CameraAccessException { return CameraManagerGlobal.get().getConcurrentCameraIds(); return CameraManagerGlobal.get().getConcurrentCameraIds(mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); } /** Loading Loading @@ -418,7 +420,8 @@ public final class CameraManager { @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig) throws CameraAccessException { return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported( cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion); cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion, mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); } /** Loading Loading @@ -794,7 +797,7 @@ public final class CameraManager { boolean hasConcurrentStreams = CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId, mContext.getDeviceId()); mContext.getDeviceId(), getDevicePolicyFromContext(mContext)); metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams); Size displaySize = getDisplaySize(); Loading Loading @@ -2097,7 +2100,7 @@ public final class CameraManager { // Opened Camera ID -> apk name map private final ArrayMap<DeviceCameraInfo, String> mOpenedDevices = new ArrayMap<>(); private final Set<Set<String>> mConcurrentCameraIdCombinations = new ArraySet<>(); private final Set<Set<DeviceCameraInfo>> mConcurrentCameraIdCombinations = new ArraySet<>(); // Registered availability callbacks and their executors private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>(); Loading Loading @@ -2256,7 +2259,13 @@ public final class CameraManager { ConcurrentCameraIdCombination[] cameraIdCombinations = cameraService.getConcurrentCameraIds(); for (ConcurrentCameraIdCombination comb : cameraIdCombinations) { mConcurrentCameraIdCombinations.add(comb.getConcurrentCameraIdCombination()); Set<Pair<String, Integer>> combination = comb.getConcurrentCameraIdCombination(); Set<DeviceCameraInfo> deviceCameraInfoSet = new ArraySet<>(); for (Pair<String, Integer> entry : combination) { deviceCameraInfoSet.add(new DeviceCameraInfo(entry.first, entry.second)); } mConcurrentCameraIdCombinations.add(deviceCameraInfoSet); } } catch (ServiceSpecificException e) { // Unexpected failure Loading Loading @@ -2341,13 +2350,12 @@ public final class CameraManager { return cameraIds.toArray(new String[0]); } private Set<Set<String>> extractConcurrentCameraIdListLocked() { private Set<Set<String>> extractConcurrentCameraIdListLocked(int deviceId, int devicePolicy) { Set<Set<String>> concurrentCameraIds = new ArraySet<>(); for (Set<String> cameraIds : mConcurrentCameraIdCombinations) { for (Set<DeviceCameraInfo> deviceCameraInfos : mConcurrentCameraIdCombinations) { Set<String> extractedCameraIds = new ArraySet<>(); for (String cameraId : cameraIds) { // TODO(b/291736219): This to be made device-aware. DeviceCameraInfo info = new DeviceCameraInfo(cameraId, DEVICE_ID_DEFAULT); for (DeviceCameraInfo info : deviceCameraInfos) { // if the camera id status is NOT_PRESENT or ENUMERATING; skip the device. // TODO: Would a device status NOT_PRESENT ever be in the map ? it gets removed // in the callback anyway. Loading @@ -2360,10 +2368,15 @@ public final class CameraManager { || status == ICameraServiceListener.STATUS_NOT_PRESENT) { continue; } extractedCameraIds.add(cameraId); if (shouldHideCamera(deviceId, devicePolicy, info)) { continue; } extractedCameraIds.add(info.mCameraId); } if (!extractedCameraIds.isEmpty()) { concurrentCameraIds.add(extractedCameraIds); } } return concurrentCameraIds; } Loading Loading @@ -2523,12 +2536,13 @@ public final class CameraManager { return cameraIds; } public @NonNull Set<Set<String>> getConcurrentCameraIds() { public @NonNull Set<Set<String>> getConcurrentCameraIds(int deviceId, int devicePolicy) { Set<Set<String>> concurrentStreamingCameraIds; synchronized (mLock) { // Try to make sure we have an up-to-date list of concurrent camera devices. connectCameraServiceLocked(); concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked(); concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked(deviceId, devicePolicy); } // TODO: Some sort of sorting ? return concurrentStreamingCameraIds; Loading @@ -2536,13 +2550,12 @@ public final class CameraManager { public boolean isConcurrentSessionConfigurationSupported( @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations, int targetSdkVersion) throws CameraAccessException { int targetSdkVersion, int deviceId, int devicePolicy) throws CameraAccessException { if (cameraIdsAndSessionConfigurations == null) { throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null"); } // TODO(b/291736219): Check if this API needs to be made device-aware. int size = cameraIdsAndSessionConfigurations.size(); if (size == 0) { throw new IllegalArgumentException("camera id and session combination is empty"); Loading @@ -2552,8 +2565,14 @@ public final class CameraManager { // Go through all the elements and check if the camera ids are valid at least / // belong to one of the combinations returned by getConcurrentCameraIds() boolean subsetFound = false; for (Set<String> combination : mConcurrentCameraIdCombinations) { if (combination.containsAll(cameraIdsAndSessionConfigurations.keySet())) { for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) { Set<DeviceCameraInfo> infos = new ArraySet<>(); for (String cameraId : cameraIdsAndSessionConfigurations.keySet()) { infos.add(new DeviceCameraInfo(cameraId, devicePolicy == DEVICE_POLICY_DEFAULT ? DEVICE_ID_DEFAULT : deviceId)); } if (combination.containsAll(infos)) { subsetFound = true; } } Loading @@ -2573,7 +2592,7 @@ public final class CameraManager { } try { return mCameraService.isConcurrentSessionConfigurationSupported( cameraIdsAndConfigs, targetSdkVersion); cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy); } catch (ServiceSpecificException e) { throw ExceptionUtils.throwAsPublicException(e); } catch (RemoteException e) { Loading @@ -2592,8 +2611,10 @@ public final class CameraManager { * @return Whether the camera device was found in the set of combinations returned by * getConcurrentCameraIds */ public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId) { DeviceCameraInfo info = new DeviceCameraInfo(cameraId, deviceId); public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId, int devicePolicy) { DeviceCameraInfo info = new DeviceCameraInfo(cameraId, devicePolicy == DEVICE_POLICY_DEFAULT ? DEVICE_ID_DEFAULT : deviceId); if (!mDeviceStatus.containsKey(info)) { // physical camera ids aren't advertised in concurrent camera id combinations. if (DEBUG) { Loading @@ -2602,8 +2623,8 @@ public final class CameraManager { } return false; } for (Set<String> comb : mConcurrentCameraIdCombinations) { if (comb.contains(cameraId)) { for (Set<DeviceCameraInfo> comb : mConcurrentCameraIdCombinations) { if (comb.contains(info)) { return true; } } Loading
core/java/android/hardware/camera2/utils/ConcurrentCameraIdCombination.java +23 −19 Original line number Diff line number Diff line Loading @@ -13,13 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ package android.hardware.camera2.utils; import android.annotation.NonNull; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; import android.util.Pair; import java.util.HashSet; import java.util.Set; /** Loading @@ -30,11 +32,11 @@ import java.util.Set; */ public class ConcurrentCameraIdCombination implements Parcelable { private Set<String> mConcurrentCameraIds = new HashSet<>(); private final Set<Pair<String, Integer>> mConcurrentCameraIdDeviceIdPairs = new ArraySet<>(); public static final @NonNull Parcelable.Creator<ConcurrentCameraIdCombination> CREATOR = new Parcelable.Creator<ConcurrentCameraIdCombination>() { new Parcelable.Creator<>() { @Override public ConcurrentCameraIdCombination createFromParcel(Parcel in) { return new ConcurrentCameraIdCombination(in); Loading @@ -57,9 +59,10 @@ public class ConcurrentCameraIdCombination implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mConcurrentCameraIds.size()); for (String cameraId : mConcurrentCameraIds) { dest.writeString(cameraId); dest.writeInt(mConcurrentCameraIdDeviceIdPairs.size()); for (Pair<String, Integer> cameraIdDeviceIdPair : mConcurrentCameraIdDeviceIdPairs) { dest.writeString(cameraIdDeviceIdPair.first); dest.writeInt(cameraIdDeviceIdPair.second); } } Loading @@ -67,7 +70,7 @@ public class ConcurrentCameraIdCombination implements Parcelable { * helper for CREATOR */ public void readFromParcel(Parcel in) { mConcurrentCameraIds.clear(); mConcurrentCameraIdDeviceIdPairs.clear(); int cameraCombinationSize = in.readInt(); if (cameraCombinationSize < 0) { throw new RuntimeException("cameraCombinationSize " + cameraCombinationSize Loading @@ -78,14 +81,15 @@ public class ConcurrentCameraIdCombination implements Parcelable { if (cameraId == null) { throw new RuntimeException("Failed to read camera id from Parcel"); } mConcurrentCameraIds.add(cameraId); int deviceId = in.readInt(); mConcurrentCameraIdDeviceIdPairs.add(new Pair<>(cameraId, deviceId)); } } /** * Get this concurrent camera id combination. */ public Set<String> getConcurrentCameraIdCombination() { return mConcurrentCameraIds; public Set<Pair<String, Integer>> getConcurrentCameraIdCombination() { return mConcurrentCameraIdDeviceIdPairs; } }