1ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk/*
2ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * Copyright (C) 2014 The Android Open Source Project
3ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk *
4ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * Licensed under the Apache License, Version 2.0 (the "License");
5ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * you may not use this file except in compliance with the License.
6ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * You may obtain a copy of the License at
7ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk *
8ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk *      http://www.apache.org/licenses/LICENSE-2.0
9ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk *
10ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * Unless required by applicable law or agreed to in writing, software
11ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * distributed under the License is distributed on an "AS IS" BASIS,
12ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * See the License for the specific language governing permissions and
14ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * limitations under the License.
15ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk */
16ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
17ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkpackage android.hardware.camera2.legacy;
18ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
195d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport android.hardware.ICameraService;
205d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport android.os.ServiceSpecificException;
21ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkimport android.util.AndroidException;
22ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
235d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvalaimport static android.system.OsConstants.*;
248ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic
25ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk/**
26ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk * Utility class containing exception handling used solely by the compatibility mode shim.
27ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk */
28ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunkpublic class LegacyExceptionUtils {
29ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    private static final String TAG = "LegacyExceptionUtils";
30ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
315d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int NO_ERROR = 0;
325d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int PERMISSION_DENIED = -EPERM;
335d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int ALREADY_EXISTS = -EEXIST;
345d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int BAD_VALUE = -EINVAL;
355d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int DEAD_OBJECT = -ENOSYS;
365d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int INVALID_OPERATION = -EPIPE;
375d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static final int TIMED_OUT = -ETIMEDOUT;
385d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala
39ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    /**
40ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * Checked exception thrown when a BufferQueue has been abandoned by its consumer.
41ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     */
42ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    public static class BufferQueueAbandonedException extends AndroidException {
43ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        public BufferQueueAbandonedException () {}
44ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
45ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        public BufferQueueAbandonedException(String name) {
46ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk            super(name);
47ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        }
48ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
49ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        public BufferQueueAbandonedException(String name, Throwable cause) {
50ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk            super(name, cause);
51ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        }
52ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
53ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        public BufferQueueAbandonedException(Exception cause) {
54ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk            super(cause);
55ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        }
56ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    }
57ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
58ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    /**
59ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * Throw error codes used by legacy device methods as exceptions.
60ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     *
61ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * <p>Non-negative return values are passed through, negative return values are thrown as
62ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * exceptions.</p>
63ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     *
64ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * @param errorFlag error to throw as an exception.
658ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic     * @throws {@link BufferQueueAbandonedException} for -ENODEV.
66ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * @throws {@link UnsupportedOperationException} for an unknown negative error code.
67ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     * @return {@code errorFlag} if the value was non-negative, throws otherwise.
68ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk     */
69ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    public static int throwOnError(int errorFlag) throws BufferQueueAbandonedException {
705d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        if (errorFlag == NO_ERROR) {
715d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            return NO_ERROR;
728ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic        } else if (errorFlag == -ENODEV) {
738ea56f68517ffa42bd5f43ab67f4ebfcfcb0cd23Lazar Trsic            throw new BufferQueueAbandonedException();
74ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        }
75ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
76ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        if (errorFlag < 0) {
77ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk            throw new UnsupportedOperationException("Unknown error " + errorFlag);
78ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        }
79ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        return errorFlag;
80ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    }
81ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk
825d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    /**
835d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala     * Throw error codes returned by the camera service as exceptions.
845d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala     *
855d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala     * @param errorFlag error to throw as an exception.
865d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala     */
875d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    public static void throwOnServiceError(int errorFlag) {
885d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        int errorCode = ICameraService.ERROR_INVALID_OPERATION;
895d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        String errorMsg;
905d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala
915d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        if (errorFlag >= NO_ERROR) {
925d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            return;
935d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == PERMISSION_DENIED) {
945d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_PERMISSION_DENIED;
955d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Lacking privileges to access camera service";
965d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == ALREADY_EXISTS) {
975d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            // This should be handled at the call site. Typically this isn't bad,
985d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            // just means we tried to do an operation that already completed.
995d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            return;
1005d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == BAD_VALUE) {
1015d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_ILLEGAL_ARGUMENT;
1025d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Bad argument passed to camera service";
1035d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == DEAD_OBJECT) {
1045d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_DISCONNECTED;
1055d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Camera service not available";
1065d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == TIMED_OUT) {
1075d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_INVALID_OPERATION;
1085d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Operation timed out in camera service";
1095d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == -EACCES) {
1105d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_DISABLED;
1115d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Camera disabled by policy";
1125d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == -EBUSY) {
1135d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_CAMERA_IN_USE;
1145d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Camera already in use";
1155d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == -EUSERS) {
1165d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_MAX_CAMERAS_IN_USE;
1175d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Maximum number of cameras in use";
1185d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == -ENODEV) {
1195d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_DISCONNECTED;
1205d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Camera device not available";
1215d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == -EOPNOTSUPP) {
1225d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_DEPRECATED_HAL;
1235d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Deprecated camera HAL does not support this";
1245d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else if (errorFlag == INVALID_OPERATION) {
1255d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_INVALID_OPERATION;
1265d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Illegal state encountered in camera service.";
1275d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        } else {
1285d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorCode = ICameraService.ERROR_INVALID_OPERATION;
1295d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala            errorMsg = "Unknown camera device error " + errorFlag;
1305d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        }
1315d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala
1325d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala        throw new ServiceSpecificException(errorCode, errorMsg);
1335d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala    }
1345d2d7788f1759b0f3d2c057af0b3ea61b0354feeEino-Ville Talvala
135ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    private LegacyExceptionUtils() {
136ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk        throw new AssertionError();
137ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk    }
138ef14da32804b06bac872c9e0e14ce0e52120a0bdRuben Brunk}
139