Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 699af642 authored by Biswarup Pal's avatar Biswarup Pal Committed by Android (Google) Code Review
Browse files

Merge "Add device-awareness for camera concurrency API's" into main

parents 5f9a9307 decccc47
Loading
Loading
Loading
Loading
+46 −25
Original line number Original line Diff line number Diff line
@@ -69,6 +69,7 @@ import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.Log;
import android.util.Log;
import android.util.Pair;
import android.util.Size;
import android.util.Size;
import android.view.Display;
import android.view.Display;


@@ -379,7 +380,8 @@ public final class CameraManager {
     */
     */
    @NonNull
    @NonNull
    public Set<Set<String>> getConcurrentCameraIds() throws CameraAccessException {
    public Set<Set<String>> getConcurrentCameraIds() throws CameraAccessException {
        return CameraManagerGlobal.get().getConcurrentCameraIds();
        return CameraManagerGlobal.get().getConcurrentCameraIds(mContext.getDeviceId(),
                getDevicePolicyFromContext(mContext));
    }
    }


    /**
    /**
@@ -418,7 +420,8 @@ public final class CameraManager {
            @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig)
            @NonNull Map<String, SessionConfiguration> cameraIdAndSessionConfig)
            throws CameraAccessException {
            throws CameraAccessException {
        return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported(
        return CameraManagerGlobal.get().isConcurrentSessionConfigurationSupported(
                cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion);
                cameraIdAndSessionConfig, mContext.getApplicationInfo().targetSdkVersion,
                mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
    }
    }


    /**
    /**
@@ -794,7 +797,7 @@ public final class CameraManager {


            boolean hasConcurrentStreams =
            boolean hasConcurrentStreams =
                    CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
                    CameraManagerGlobal.get().cameraIdHasConcurrentStreamsLocked(cameraId,
                            mContext.getDeviceId());
                            mContext.getDeviceId(), getDevicePolicyFromContext(mContext));
            metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams);
            metadata.setHasMandatoryConcurrentStreams(hasConcurrentStreams);


            Size displaySize = getDisplaySize();
            Size displaySize = getDisplaySize();
@@ -2097,7 +2100,7 @@ public final class CameraManager {
        // Opened Camera ID -> apk name map
        // Opened Camera ID -> apk name map
        private final ArrayMap<DeviceCameraInfo, String> mOpenedDevices = new ArrayMap<>();
        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
        // Registered availability callbacks and their executors
        private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>();
        private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap = new ArrayMap<>();
@@ -2256,7 +2259,13 @@ public final class CameraManager {
                ConcurrentCameraIdCombination[] cameraIdCombinations =
                ConcurrentCameraIdCombination[] cameraIdCombinations =
                        cameraService.getConcurrentCameraIds();
                        cameraService.getConcurrentCameraIds();
                for (ConcurrentCameraIdCombination comb : cameraIdCombinations) {
                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) {
            } catch (ServiceSpecificException e) {
                // Unexpected failure
                // Unexpected failure
@@ -2341,13 +2350,12 @@ public final class CameraManager {
            return cameraIds.toArray(new String[0]);
            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<>();
            Set<Set<String>> concurrentCameraIds = new ArraySet<>();
            for (Set<String> cameraIds : mConcurrentCameraIdCombinations) {
            for (Set<DeviceCameraInfo> deviceCameraInfos : mConcurrentCameraIdCombinations) {
                Set<String> extractedCameraIds = new ArraySet<>();
                Set<String> extractedCameraIds = new ArraySet<>();
                for (String cameraId : cameraIds) {
                for (DeviceCameraInfo info : deviceCameraInfos) {
                    // TODO(b/291736219): This to be made device-aware.
                    DeviceCameraInfo info = new DeviceCameraInfo(cameraId, DEVICE_ID_DEFAULT);
                    // if the camera id status is NOT_PRESENT or ENUMERATING; skip the device.
                    // 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
                    // TODO: Would a device status NOT_PRESENT ever be in the map ? it gets removed
                    // in the callback anyway.
                    // in the callback anyway.
@@ -2360,10 +2368,15 @@ public final class CameraManager {
                            || status == ICameraServiceListener.STATUS_NOT_PRESENT) {
                            || status == ICameraServiceListener.STATUS_NOT_PRESENT) {
                        continue;
                        continue;
                    }
                    }
                    extractedCameraIds.add(cameraId);
                    if (shouldHideCamera(deviceId, devicePolicy, info)) {
                        continue;
                    }
                    }
                    extractedCameraIds.add(info.mCameraId);
                }
                if (!extractedCameraIds.isEmpty()) {
                    concurrentCameraIds.add(extractedCameraIds);
                    concurrentCameraIds.add(extractedCameraIds);
                }
                }
            }
            return concurrentCameraIds;
            return concurrentCameraIds;
        }
        }


@@ -2523,12 +2536,13 @@ public final class CameraManager {
            return cameraIds;
            return cameraIds;
        }
        }


        public @NonNull Set<Set<String>> getConcurrentCameraIds() {
        public @NonNull Set<Set<String>> getConcurrentCameraIds(int deviceId, int devicePolicy) {
            Set<Set<String>> concurrentStreamingCameraIds;
            Set<Set<String>> concurrentStreamingCameraIds;
            synchronized (mLock) {
            synchronized (mLock) {
                // Try to make sure we have an up-to-date list of concurrent camera devices.
                // Try to make sure we have an up-to-date list of concurrent camera devices.
                connectCameraServiceLocked();
                connectCameraServiceLocked();
                concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked();
                concurrentStreamingCameraIds = extractConcurrentCameraIdListLocked(deviceId,
                        devicePolicy);
            }
            }
            // TODO: Some sort of sorting  ?
            // TODO: Some sort of sorting  ?
            return concurrentStreamingCameraIds;
            return concurrentStreamingCameraIds;
@@ -2536,13 +2550,12 @@ public final class CameraManager {


        public boolean isConcurrentSessionConfigurationSupported(
        public boolean isConcurrentSessionConfigurationSupported(
                @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations,
                @NonNull Map<String, SessionConfiguration> cameraIdsAndSessionConfigurations,
                int targetSdkVersion) throws CameraAccessException {
                int targetSdkVersion, int deviceId, int devicePolicy)
                throws CameraAccessException {
            if (cameraIdsAndSessionConfigurations == null) {
            if (cameraIdsAndSessionConfigurations == null) {
                throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null");
                throw new IllegalArgumentException("cameraIdsAndSessionConfigurations was null");
            }
            }


            // TODO(b/291736219): Check if this API needs to be made device-aware.

            int size = cameraIdsAndSessionConfigurations.size();
            int size = cameraIdsAndSessionConfigurations.size();
            if (size == 0) {
            if (size == 0) {
                throw new IllegalArgumentException("camera id and session combination is empty");
                throw new IllegalArgumentException("camera id and session combination is empty");
@@ -2552,8 +2565,14 @@ public final class CameraManager {
                // Go through all the elements and check if the camera ids are valid at least /
                // Go through all the elements and check if the camera ids are valid at least /
                // belong to one of the combinations returned by getConcurrentCameraIds()
                // belong to one of the combinations returned by getConcurrentCameraIds()
                boolean subsetFound = false;
                boolean subsetFound = false;
                for (Set<String> combination : mConcurrentCameraIdCombinations) {
                for (Set<DeviceCameraInfo> combination : mConcurrentCameraIdCombinations) {
                    if (combination.containsAll(cameraIdsAndSessionConfigurations.keySet())) {
                    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;
                        subsetFound = true;
                    }
                    }
                }
                }
@@ -2573,7 +2592,7 @@ public final class CameraManager {
                }
                }
                try {
                try {
                    return mCameraService.isConcurrentSessionConfigurationSupported(
                    return mCameraService.isConcurrentSessionConfigurationSupported(
                            cameraIdsAndConfigs, targetSdkVersion);
                            cameraIdsAndConfigs, targetSdkVersion, deviceId, devicePolicy);
                } catch (ServiceSpecificException e) {
                } catch (ServiceSpecificException e) {
                    throw ExceptionUtils.throwAsPublicException(e);
                    throw ExceptionUtils.throwAsPublicException(e);
                } catch (RemoteException e) {
                } catch (RemoteException e) {
@@ -2592,8 +2611,10 @@ public final class CameraManager {
         * @return Whether the camera device was found in the set of combinations returned by
         * @return Whether the camera device was found in the set of combinations returned by
         *         getConcurrentCameraIds
         *         getConcurrentCameraIds
         */
         */
        public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId) {
        public boolean cameraIdHasConcurrentStreamsLocked(String cameraId, int deviceId,
            DeviceCameraInfo info = new DeviceCameraInfo(cameraId, deviceId);
                int devicePolicy) {
            DeviceCameraInfo info = new DeviceCameraInfo(cameraId,
                    devicePolicy == DEVICE_POLICY_DEFAULT ? DEVICE_ID_DEFAULT : deviceId);
            if (!mDeviceStatus.containsKey(info)) {
            if (!mDeviceStatus.containsKey(info)) {
                // physical camera ids aren't advertised in concurrent camera id combinations.
                // physical camera ids aren't advertised in concurrent camera id combinations.
                if (DEBUG) {
                if (DEBUG) {
@@ -2602,8 +2623,8 @@ public final class CameraManager {
                }
                }
                return false;
                return false;
            }
            }
            for (Set<String> comb : mConcurrentCameraIdCombinations) {
            for (Set<DeviceCameraInfo> comb : mConcurrentCameraIdCombinations) {
                if (comb.contains(cameraId)) {
                if (comb.contains(info)) {
                    return true;
                    return true;
                }
                }
            }
            }
+23 −19
Original line number Original line Diff line number Diff line
@@ -13,13 +13,15 @@
 * See the License for the specific language governing permissions and
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * limitations under the License.
 */
 */

package android.hardware.camera2.utils;
package android.hardware.camera2.utils;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.util.ArraySet;
import android.util.Pair;


import java.util.HashSet;
import java.util.Set;
import java.util.Set;


/**
/**
@@ -30,11 +32,11 @@ import java.util.Set;
 */
 */
public class ConcurrentCameraIdCombination implements Parcelable {
public class ConcurrentCameraIdCombination implements Parcelable {


    private Set<String> mConcurrentCameraIds = new HashSet<>();
    private final Set<Pair<String, Integer>> mConcurrentCameraIdDeviceIdPairs = new ArraySet<>();


    public static final @NonNull
    public static final @NonNull
            Parcelable.Creator<ConcurrentCameraIdCombination> CREATOR =
            Parcelable.Creator<ConcurrentCameraIdCombination> CREATOR =
            new Parcelable.Creator<ConcurrentCameraIdCombination>() {
            new Parcelable.Creator<>() {
                @Override
                @Override
                public ConcurrentCameraIdCombination createFromParcel(Parcel in) {
                public ConcurrentCameraIdCombination createFromParcel(Parcel in) {
                    return new ConcurrentCameraIdCombination(in);
                    return new ConcurrentCameraIdCombination(in);
@@ -57,9 +59,10 @@ public class ConcurrentCameraIdCombination implements Parcelable {


    @Override
    @Override
    public void writeToParcel(Parcel dest, int flags) {
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mConcurrentCameraIds.size());
        dest.writeInt(mConcurrentCameraIdDeviceIdPairs.size());
        for (String cameraId : mConcurrentCameraIds) {
        for (Pair<String, Integer> cameraIdDeviceIdPair : mConcurrentCameraIdDeviceIdPairs) {
            dest.writeString(cameraId);
            dest.writeString(cameraIdDeviceIdPair.first);
            dest.writeInt(cameraIdDeviceIdPair.second);
        }
        }
    }
    }


@@ -67,7 +70,7 @@ public class ConcurrentCameraIdCombination implements Parcelable {
     * helper for CREATOR
     * helper for CREATOR
     */
     */
    public void readFromParcel(Parcel in) {
    public void readFromParcel(Parcel in) {
        mConcurrentCameraIds.clear();
        mConcurrentCameraIdDeviceIdPairs.clear();
        int cameraCombinationSize = in.readInt();
        int cameraCombinationSize = in.readInt();
        if (cameraCombinationSize < 0) {
        if (cameraCombinationSize < 0) {
            throw new RuntimeException("cameraCombinationSize " + cameraCombinationSize
            throw new RuntimeException("cameraCombinationSize " + cameraCombinationSize
@@ -78,14 +81,15 @@ public class ConcurrentCameraIdCombination implements Parcelable {
            if (cameraId == null) {
            if (cameraId == null) {
                throw new RuntimeException("Failed to read camera id from Parcel");
                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.
     * Get this concurrent camera id combination.
     */
     */
    public Set<String> getConcurrentCameraIdCombination() {
    public Set<Pair<String, Integer>> getConcurrentCameraIdCombination() {
        return mConcurrentCameraIds;
        return mConcurrentCameraIdDeviceIdPairs;
    }
    }
}
}