[go: nahoru, domu]

Provide camera quirks via CameraInternal

This CL creates the Quirk class, and adds an API to CameraInternal to return all the camera specific quirks related to the camera it controls.

Bug: 167414738
Test: n/a
Change-Id: I1c44807f37d1fdd25431094175f124208f25429c
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraImpl.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraImpl.java
index 675665a..e7039bf 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraImpl.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CameraImpl.java
@@ -37,6 +37,7 @@
 import androidx.camera.camera2.internal.compat.CameraAccessExceptionCompat;
 import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
 import androidx.camera.camera2.internal.compat.CameraManagerCompat;
+import androidx.camera.camera2.internal.compat.quirk.CameraQuirks;
 import androidx.camera.core.CameraUnavailableException;
 import androidx.camera.core.Logger;
 import androidx.camera.core.Preview;
@@ -50,6 +51,7 @@
 import androidx.camera.core.impl.ImmediateSurface;
 import androidx.camera.core.impl.LiveDataObservable;
 import androidx.camera.core.impl.Observable;
+import androidx.camera.core.impl.Quirks;
 import androidx.camera.core.impl.SessionConfig;
 import androidx.camera.core.impl.SessionConfig.ValidatingBuilder;
 import androidx.camera.core.impl.UseCaseAttachState;
@@ -166,6 +168,9 @@
     private final SynchronizedCaptureSessionOpener.Builder mCaptureSessionOpenerBuilder;
     private final Set<String> mNotifyStateAttachedSet = new HashSet<>();
 
+    @NonNull
+    private final Quirks mCameraQuirks;
+
     /**
      * Constructor for a camera.
      *
@@ -197,6 +202,7 @@
         try {
             CameraCharacteristicsCompat cameraCharacteristicsCompat =
                     mCameraManager.getCameraCharacteristicsCompat(cameraId);
+            mCameraQuirks = CameraQuirks.get(cameraId, cameraCharacteristicsCompat);
             mCameraControlInternal = new Camera2CameraControlImpl(cameraCharacteristicsCompat,
                     executorScheduler, mExecutor, new ControlUpdateListenerInternal());
             mCameraInfoInternal = new Camera2CameraInfoImpl(
@@ -868,6 +874,13 @@
         return mCameraInfoInternal;
     }
 
+    /** {@inheritDoc} */
+    @NonNull
+    @Override
+    public Quirks getCameraQuirks() {
+        return mCameraQuirks;
+    }
+
     /** Opens the camera device */
     // TODO(b/124268878): Handle SecurityException and require permission in manifest.
     @SuppressLint("MissingPermission")
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java
new file mode 100644
index 0000000..1e8c4b7
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/CameraQuirks.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2020 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.internal.compat.quirk;
+
+import android.hardware.camera2.CameraCharacteristics;
+
+import androidx.annotation.NonNull;
+import androidx.camera.camera2.internal.compat.CameraCharacteristicsCompat;
+import androidx.camera.core.impl.Quirk;
+import androidx.camera.core.impl.Quirks;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Provider of camera specific quirks. */
+public class CameraQuirks {
+
+    private CameraQuirks() {
+    }
+
+    /**
+     * Goes through all defined camera specific quirks, then filters them to retrieve quirks
+     * required for the camera identified by the provided camera id and
+     * {@link CameraCharacteristics}.
+     *
+     * @param cameraId                    Camera id of the camera device  used to filter quirks
+     * @param cameraCharacteristicsCompat Characteristics of the camera device user to filter quirks
+     * @return List of quirks associated with the camera identified by its id and
+     * {@link CameraCharacteristics}.
+     */
+    @NonNull
+    public static Quirks get(@NonNull final String cameraId,
+            @NonNull final CameraCharacteristicsCompat cameraCharacteristicsCompat) {
+        final List<Quirk> quirks = new ArrayList<>();
+        // Go through all defined camera quirks, and add them to `quirks` if they should be loaded
+        return new Quirks(quirks);
+    }
+}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/package-info.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/package-info.java
new file mode 100644
index 0000000..833ba72
--- /dev/null
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/compat/quirk/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+/**
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+package androidx.camera.camera2.internal.compat.quirk;
+
+import androidx.annotation.RestrictTo;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInternal.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInternal.java
index e163dd7..12e8409 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInternal.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CameraInternal.java
@@ -150,6 +150,10 @@
     @NonNull
     CameraInfoInternal getCameraInfoInternal();
 
+    /** Returns a list of quirks related to the camera. */
+    @NonNull
+    Quirks getCameraQuirks();
+
     ////////////////////////////////////////////////////////////////////////////////////////////////
     // Camera interface
     ////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirk.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirk.java
new file mode 100644
index 0000000..48a8fd2
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirk.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 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.core.impl;
+
+/**
+ * Defines an inconsistency, a limitation, or any behavior that deviates from the standard behavior.
+ *
+ * <p> This class is used to define both device specific and camera specific quirks. Device
+ * specific quirks depend on device related information, such as the device's brand, model and OS
+ * level. Whereas camera related quirks depend on the camera id and/or camera characteristics.
+ *
+ * @see Quirks
+ */
+public interface Quirk {
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirks.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirks.java
new file mode 100644
index 0000000..2246074
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/Quirks.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020 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.core.impl;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Wraps a list of {@link Quirk}s, allowing to easily retrieve a {@link Quirk} instance by its
+ * class.
+ */
+public class Quirks {
+
+    @NonNull
+    private final List<Quirk> mQuirks;
+
+    /** Wraps the provided list of quirks. */
+    public Quirks(@NonNull final List<Quirk> quirks) {
+        mQuirks = new ArrayList<>(quirks);
+    }
+
+    /**
+     * Retrieves a {@link Quirk} instance given its type.
+     *
+     * @param quirkClass The type of quirk to retrieve.
+     * @return A {@link Quirk} instance of the provided type, or {@code null} if it isn't found.
+     */
+    @SuppressWarnings("unchecked")
+    @Nullable
+    public <T extends Quirk> T get(@NonNull final Class<T> quirkClass) {
+        for (final Quirk quirk : mQuirks) {
+            if (quirk.getClass() == quirkClass) {
+                return (T) quirk;
+            }
+        }
+        return null;
+    }
+}
diff --git a/camera/camera-core/src/test/java/androidx/camera/core/impl/QuirksTest.java b/camera/camera-core/src/test/java/androidx/camera/core/impl/QuirksTest.java
new file mode 100644
index 0000000..d880ad5
--- /dev/null
+++ b/camera/camera-core/src/test/java/androidx/camera/core/impl/QuirksTest.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2020 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.core.impl;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class QuirksTest {
+
+    @Test
+    public void returnInstanceOfExistentQuirk() {
+        final Quirk1 quirk1 = new Quirk1();
+        final Quirk2 quirk2 = new Quirk2();
+
+        final List<Quirk> allQuirks = new ArrayList<>();
+        allQuirks.add(quirk1);
+        allQuirks.add(quirk2);
+
+        final Quirks quirks = new Quirks(allQuirks);
+
+        assertThat(quirks.get(Quirk1.class)).isEqualTo(quirk1);
+        assertThat(quirks.get(Quirk2.class)).isEqualTo(quirk2);
+    }
+
+    @Test
+    public void returnNullForInexistentQuirk() {
+        final Quirk1 quirk1 = new Quirk1();
+        final Quirk2 quirk2 = new Quirk2();
+
+        final List<Quirk> allQuirks = new ArrayList<>();
+        allQuirks.add(quirk1);
+        allQuirks.add(quirk2);
+
+        final Quirks quirks = new Quirks(allQuirks);
+
+        assertThat(quirks.get(Quirk3.class)).isNull();
+    }
+
+    static class Quirk1 implements Quirk {
+    }
+
+    static class Quirk2 implements Quirk {
+    }
+
+    static class Quirk3 implements Quirk {
+    }
+}
diff --git a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
index 3a6ef21..f020ad2 100644
--- a/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
+++ b/camera/camera-testing/src/main/java/androidx/camera/testing/fakes/FakeCamera.java
@@ -31,6 +31,8 @@
 import androidx.camera.core.impl.DeferrableSurface;
 import androidx.camera.core.impl.LiveDataObservable;
 import androidx.camera.core.impl.Observable;
+import androidx.camera.core.impl.Quirk;
+import androidx.camera.core.impl.Quirks;
 import androidx.camera.core.impl.SessionConfig;
 import androidx.camera.core.impl.UseCaseAttachState;
 import androidx.camera.core.impl.utils.futures.Futures;
@@ -70,6 +72,9 @@
 
     private List<DeferrableSurface> mConfiguredDeferrableSurfaces = Collections.emptyList();
 
+    @NonNull
+    private final List<Quirk> mCameraQuirks = Collections.emptyList();
+
     public FakeCamera() {
         this(DEFAULT_CAMERA_ID, /*cameraControl=*/null,
                 new FakeCameraInfoInternal(DEFAULT_CAMERA_ID));
@@ -295,6 +300,17 @@
         return mCameraInfoInternal;
     }
 
+    @NonNull
+    @Override
+    public Quirks getCameraQuirks() {
+        return new Quirks(mCameraQuirks);
+    }
+
+    /** Adds a quirk to the list of this camera's quirks. */
+    public void addCameraQuirk(@NonNull final Quirk quirk) {
+        mCameraQuirks.add(quirk);
+    }
+
     private void checkNotReleased() {
         if (mState == State.RELEASED) {
             throw new IllegalStateException("Camera has been released.");