xref: /aosp_15_r20/frameworks/native/include/gui/AidlUtil.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <android/gui/ARect.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/Status.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <ui/Rect.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker // Originally extracted from frameworks/av/media/libaudioclient/include/media/AidlConversionUtil.h
24*38e8c45fSAndroid Build Coastguard Worker namespace android::gui::aidl_utils {
25*38e8c45fSAndroid Build Coastguard Worker 
26*38e8c45fSAndroid Build Coastguard Worker /**
27*38e8c45fSAndroid Build Coastguard Worker  * Return the equivalent Android status_t from a binder exception code.
28*38e8c45fSAndroid Build Coastguard Worker  *
29*38e8c45fSAndroid Build Coastguard Worker  * Generally one should use statusTFromBinderStatus() instead.
30*38e8c45fSAndroid Build Coastguard Worker  *
31*38e8c45fSAndroid Build Coastguard Worker  * Exception codes can be generated from a remote Java service exception, translate
32*38e8c45fSAndroid Build Coastguard Worker  * them for use on the Native side.
33*38e8c45fSAndroid Build Coastguard Worker  *
34*38e8c45fSAndroid Build Coastguard Worker  * Note: for EX_TRANSACTION_FAILED and EX_SERVICE_SPECIFIC a more detailed error code
35*38e8c45fSAndroid Build Coastguard Worker  * can be found from transactionError() or serviceSpecificErrorCode().
36*38e8c45fSAndroid Build Coastguard Worker  */
statusTFromExceptionCode(int32_t exceptionCode)37*38e8c45fSAndroid Build Coastguard Worker static inline status_t statusTFromExceptionCode(int32_t exceptionCode) {
38*38e8c45fSAndroid Build Coastguard Worker     using namespace ::android::binder;
39*38e8c45fSAndroid Build Coastguard Worker     switch (exceptionCode) {
40*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_NONE:
41*38e8c45fSAndroid Build Coastguard Worker             return OK;
42*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
43*38e8c45fSAndroid Build Coastguard Worker             return PERMISSION_DENIED;
44*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_BAD_PARCELABLE:   // Java BadParcelableException, rethrows in Java
45*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
46*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_NULL_POINTER:     // Java NullPointerException, rethrows in Java
47*38e8c45fSAndroid Build Coastguard Worker             return BAD_VALUE;
48*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_ILLEGAL_STATE:         // Java IllegalStateException, rethrows in Java
49*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
50*38e8c45fSAndroid Build Coastguard Worker             return INVALID_OPERATION;
51*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_HAS_REPLY_HEADER: // Native strictmode violation
52*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
53*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
54*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_TRANSACTION_FAILED:  // Native - see error code
55*38e8c45fSAndroid Build Coastguard Worker         case Status::EX_SERVICE_SPECIFIC:    // Java ServiceSpecificException,
56*38e8c45fSAndroid Build Coastguard Worker                                              // rethrows in Java with integer error code
57*38e8c45fSAndroid Build Coastguard Worker             return UNKNOWN_ERROR;
58*38e8c45fSAndroid Build Coastguard Worker     }
59*38e8c45fSAndroid Build Coastguard Worker     return UNKNOWN_ERROR;
60*38e8c45fSAndroid Build Coastguard Worker }
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker /**
63*38e8c45fSAndroid Build Coastguard Worker  * Return the equivalent Android status_t from a binder status.
64*38e8c45fSAndroid Build Coastguard Worker  *
65*38e8c45fSAndroid Build Coastguard Worker  * Used to handle errors from a AIDL method declaration
66*38e8c45fSAndroid Build Coastguard Worker  *
67*38e8c45fSAndroid Build Coastguard Worker  * [oneway] void method(type0 param0, ...)
68*38e8c45fSAndroid Build Coastguard Worker  *
69*38e8c45fSAndroid Build Coastguard Worker  * or the following (where return_type is not a status_t)
70*38e8c45fSAndroid Build Coastguard Worker  *
71*38e8c45fSAndroid Build Coastguard Worker  * return_type method(type0 param0, ...)
72*38e8c45fSAndroid Build Coastguard Worker  */
statusTFromBinderStatus(const::android::binder::Status & status)73*38e8c45fSAndroid Build Coastguard Worker static inline status_t statusTFromBinderStatus(const ::android::binder::Status& status) {
74*38e8c45fSAndroid Build Coastguard Worker     return status.isOk() ? OK // check OK,
75*38e8c45fSAndroid Build Coastguard Worker         : status.serviceSpecificErrorCode() // service-side error, not standard Java exception
76*38e8c45fSAndroid Build Coastguard Worker                                             // (fromServiceSpecificError)
77*38e8c45fSAndroid Build Coastguard Worker         ?: status.transactionError() // a native binder transaction error (fromStatusT)
78*38e8c45fSAndroid Build Coastguard Worker         ?: statusTFromExceptionCode(status.exceptionCode()); // a service-side error with a
79*38e8c45fSAndroid Build Coastguard Worker                                                     // standard Java exception (fromExceptionCode)
80*38e8c45fSAndroid Build Coastguard Worker }
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker /**
83*38e8c45fSAndroid Build Coastguard Worker  * Return a binder::Status from native service status.
84*38e8c45fSAndroid Build Coastguard Worker  *
85*38e8c45fSAndroid Build Coastguard Worker  * This is used for methods not returning an explicit status_t,
86*38e8c45fSAndroid Build Coastguard Worker  * where Java callers expect an exception, not an integer return value.
87*38e8c45fSAndroid Build Coastguard Worker  */
88*38e8c45fSAndroid Build Coastguard Worker static inline ::android::binder::Status binderStatusFromStatusT(
89*38e8c45fSAndroid Build Coastguard Worker         status_t status, const char* optionalMessage = nullptr) {
90*38e8c45fSAndroid Build Coastguard Worker     const char* const emptyIfNull = optionalMessage == nullptr ? "" : optionalMessage;
91*38e8c45fSAndroid Build Coastguard Worker     // From binder::Status instructions:
92*38e8c45fSAndroid Build Coastguard Worker     //  Prefer a generic exception code when possible, then a service specific
93*38e8c45fSAndroid Build Coastguard Worker     //  code, and finally a status_t for low level failures or legacy support.
94*38e8c45fSAndroid Build Coastguard Worker     //  Exception codes and service specific errors map to nicer exceptions for
95*38e8c45fSAndroid Build Coastguard Worker     //  Java clients.
96*38e8c45fSAndroid Build Coastguard Worker 
97*38e8c45fSAndroid Build Coastguard Worker     using namespace ::android::binder;
98*38e8c45fSAndroid Build Coastguard Worker     switch (status) {
99*38e8c45fSAndroid Build Coastguard Worker         case OK:
100*38e8c45fSAndroid Build Coastguard Worker             return Status::ok();
101*38e8c45fSAndroid Build Coastguard Worker         case PERMISSION_DENIED: // throw SecurityException on Java side
102*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_SECURITY, emptyIfNull);
103*38e8c45fSAndroid Build Coastguard Worker         case BAD_VALUE: // throw IllegalArgumentException on Java side
104*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, emptyIfNull);
105*38e8c45fSAndroid Build Coastguard Worker         case INVALID_OPERATION: // throw IllegalStateException on Java side
106*38e8c45fSAndroid Build Coastguard Worker             return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, emptyIfNull);
107*38e8c45fSAndroid Build Coastguard Worker     }
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     // A service specific error will not show on status.transactionError() so
110*38e8c45fSAndroid Build Coastguard Worker     // be sure to use statusTFromBinderStatus() for reliable error handling.
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker     // throw a ServiceSpecificException.
113*38e8c45fSAndroid Build Coastguard Worker     return Status::fromServiceSpecificError(status, emptyIfNull);
114*38e8c45fSAndroid Build Coastguard Worker }
115*38e8c45fSAndroid Build Coastguard Worker 
fromARect(ARect rect)116*38e8c45fSAndroid Build Coastguard Worker static inline Rect fromARect(ARect rect) {
117*38e8c45fSAndroid Build Coastguard Worker     return Rect(rect.left, rect.top, rect.right, rect.bottom);
118*38e8c45fSAndroid Build Coastguard Worker }
119*38e8c45fSAndroid Build Coastguard Worker 
toARect(Rect rect)120*38e8c45fSAndroid Build Coastguard Worker static inline ARect toARect(Rect rect) {
121*38e8c45fSAndroid Build Coastguard Worker     ARect aRect;
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     aRect.left = rect.left;
124*38e8c45fSAndroid Build Coastguard Worker     aRect.top = rect.top;
125*38e8c45fSAndroid Build Coastguard Worker     aRect.right = rect.right;
126*38e8c45fSAndroid Build Coastguard Worker     aRect.bottom = rect.bottom;
127*38e8c45fSAndroid Build Coastguard Worker     return aRect;
128*38e8c45fSAndroid Build Coastguard Worker }
129*38e8c45fSAndroid Build Coastguard Worker 
toARect(int32_t left,int32_t top,int32_t right,int32_t bottom)130*38e8c45fSAndroid Build Coastguard Worker static inline ARect toARect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
131*38e8c45fSAndroid Build Coastguard Worker     return toARect(Rect(left, top, right, bottom));
132*38e8c45fSAndroid Build Coastguard Worker }
133*38e8c45fSAndroid Build Coastguard Worker 
toARect(int32_t width,int32_t height)134*38e8c45fSAndroid Build Coastguard Worker static inline ARect toARect(int32_t width, int32_t height) {
135*38e8c45fSAndroid Build Coastguard Worker     return toARect(Rect(width, height));
136*38e8c45fSAndroid Build Coastguard Worker }
137*38e8c45fSAndroid Build Coastguard Worker 
138*38e8c45fSAndroid Build Coastguard Worker } // namespace android::gui::aidl_utils
139