1 /*
2  * Copyright 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.camera.core.impl.utils;
18 
19 import androidx.camera.core.FocusMeteringAction;
20 import androidx.camera.core.impl.AdapterCameraInfo;
21 import androidx.camera.core.impl.SessionProcessor;
22 
23 import org.jspecify.annotations.NonNull;
24 import org.jspecify.annotations.Nullable;
25 
26 import java.util.ArrayList;
27 import java.util.List;
28 
29 /**
30  * Utility class for session processor related operations.
31  */
32 public final class SessionProcessorUtil {
SessionProcessorUtil()33     private SessionProcessorUtil() {
34 
35     }
36 
37     /**
38      * Returns whether the camera operations are supported by the SessionProcessor.
39      *
40      * @param operations the camera operations to check.
41      * @return {@code true} if the operations can be supported, otherwise {@code false}.
42      */
isOperationSupported(@ullable SessionProcessor sessionProcessor, @AdapterCameraInfo.CameraOperation int @NonNull ... operations)43     public static boolean isOperationSupported(@Nullable SessionProcessor sessionProcessor,
44             @AdapterCameraInfo.CameraOperation int @NonNull ... operations) {
45         if (sessionProcessor == null) {
46             return true;
47         }
48         // Arrays.asList doesn't work for int array.
49         List<Integer> operationList = new ArrayList<>(operations.length);
50         for (int operation : operations) {
51             operationList.add(operation);
52         }
53 
54         return sessionProcessor.getSupportedCameraOperations().containsAll(operationList);
55     }
56 
57     /**
58      * Returns the modified {@link FocusMeteringAction} that filters out unsupported AE/AF/AWB
59      * regions. Returns {@code null} if none of AF/AE/AWB regions can be supported after the
60      * filtering.
61      */
getModifiedFocusMeteringAction( @ullable SessionProcessor sessionProcessor, @NonNull FocusMeteringAction action)62     public static @Nullable FocusMeteringAction getModifiedFocusMeteringAction(
63             @Nullable SessionProcessor sessionProcessor, @NonNull FocusMeteringAction action) {
64         if (sessionProcessor == null) {
65             return action;
66         }
67         boolean shouldModify = false;
68         FocusMeteringAction.Builder builder = new FocusMeteringAction.Builder(action);
69         if (!action.getMeteringPointsAf().isEmpty()
70                 && !isOperationSupported(sessionProcessor,
71                 AdapterCameraInfo.CAMERA_OPERATION_AUTO_FOCUS,
72                 AdapterCameraInfo.CAMERA_OPERATION_AF_REGION)) {
73             shouldModify = true;
74             builder.removePoints(FocusMeteringAction.FLAG_AF);
75         }
76 
77         if (!action.getMeteringPointsAe().isEmpty()
78                 && !isOperationSupported(sessionProcessor,
79                 AdapterCameraInfo.CAMERA_OPERATION_AE_REGION)) {
80             shouldModify = true;
81             builder.removePoints(FocusMeteringAction.FLAG_AE);
82         }
83 
84         if (!action.getMeteringPointsAwb().isEmpty()
85                 && !isOperationSupported(sessionProcessor,
86                 AdapterCameraInfo.CAMERA_OPERATION_AWB_REGION)) {
87             shouldModify = true;
88             builder.removePoints(FocusMeteringAction.FLAG_AWB);
89         }
90 
91         // Returns origin action if no need to modify.
92         if (!shouldModify) {
93             return action;
94         }
95 
96         FocusMeteringAction modifyAction = builder.build();
97         if (modifyAction.getMeteringPointsAf().isEmpty()
98                 && modifyAction.getMeteringPointsAe().isEmpty()
99                 && modifyAction.getMeteringPointsAwb().isEmpty()) {
100             // All regions are not allowed, return null.
101             return null;
102         }
103         return builder.build();
104     }
105 }
106