1 /*
2  * Copyright 2023 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 #pragma once
18 
19 #include <android-base/expected.h>
20 #include <utils/Errors.h>
21 
22 namespace android::ui {
23 
24 enum class ErrorCode : int32_t {
25     /**
26      * No error.
27      */
28     None = 0,
29     /**
30      * Invalid BufferDescriptor.
31      */
32     BadDescriptor = 1,
33     /**
34      * Invalid buffer handle.
35      */
36     BadBuffer = 2,
37     /**
38      * Invalid HardwareBufferDescription.
39      */
40     BadValue = 3,
41     /**
42      * Resource unavailable.
43      */
44     NoResources = 5,
45     /**
46      * Permanent failure.
47      */
48     Unsupported = 7,
49 };
50 
51 class Error {
52 public:
Error(ErrorCode err)53     Error(ErrorCode err) : mCode(err) {}
54 
Error(ErrorCode err,std::string && message)55     Error(ErrorCode err, std::string&& message) : mCode(err), mMessage(std::move(message)) {}
Error(ErrorCode err,const std::string_view & message)56     Error(ErrorCode err, const std::string_view& message) : mCode(err), mMessage(message) {}
57 
codeToStatus(ErrorCode code)58     static constexpr status_t codeToStatus(ErrorCode code) {
59         switch (code) {
60             case ErrorCode::None:
61                 return OK;
62             case ErrorCode::BadDescriptor:
63                 return BAD_VALUE;
64             case ErrorCode::BadValue:
65                 return BAD_VALUE;
66             case ErrorCode::BadBuffer:
67                 return BAD_TYPE;
68             case ErrorCode::NoResources:
69                 return NO_MEMORY;
70             case ErrorCode::Unsupported:
71                 return INVALID_OPERATION;
72             default:
73                 return UNKNOWN_ERROR;
74         }
75     }
76 
statusToCode(status_t status)77     static constexpr ErrorCode statusToCode(status_t status) {
78         switch (status) {
79             case OK:
80                 return ErrorCode::None;
81             case BAD_VALUE:
82                 return ErrorCode::BadValue;
83             case BAD_TYPE:
84                 return ErrorCode::BadBuffer;
85             case NO_MEMORY:
86                 return ErrorCode::NoResources;
87             case INVALID_OPERATION:
88                 return ErrorCode::Unsupported;
89             default:
90                 return ErrorCode::Unsupported;
91         }
92     }
93 
asStatus()94     constexpr status_t asStatus() const { return codeToStatus(mCode); }
95 
code()96     ErrorCode code() const { return mCode; }
97 
message()98     const std::string& message() const { return mMessage; }
99 
100     bool operator==(const ErrorCode code) { return mCode == code; }
101 
102 private:
103     ErrorCode mCode;
104     std::string mMessage;
105 };
106 
107 template <typename T>
108 class Result : public base::expected<T, Error> {
109 public:
110     using base::expected<T, Error>::expected;
111 
asStatus()112     [[nodiscard]] constexpr status_t asStatus() const {
113         return this->has_value() ? OK : this->error().asStatus();
114     }
115 
errorCode()116     [[nodiscard]] constexpr ErrorCode errorCode() const {
117         return this->has_value() ? ErrorCode::None : this->error().code();
118     }
119 };
120 
121 } // namespace android::ui
122