1 /*
2  * Copyright (C) 2022 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 com.android.car.internal.property;
18 
19 import static com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport.PRIVATE_CONSTRUCTOR;
20 import static com.android.car.internal.common.CommonConstants.EMPTY_BYTE_ARRAY;
21 import static com.android.car.internal.property.VehiclePropertyIdDebugUtils.isDefined;
22 import static com.android.car.internal.property.VehiclePropertyIdDebugUtils.toDebugString;
23 
24 import android.car.VehiclePropertyIds;
25 import android.car.hardware.CarPropertyValue;
26 
27 import com.android.car.internal.ExcludeFromCodeCoverageGeneratedReport;
28 
29 import java.util.Collection;
30 import java.util.StringJoiner;
31 
32 /**
33  * Helper class for CarPropertyService/CarPropertyManager.
34  *
35  * @hide
36  */
37 public final class CarPropertyHelper {
38     /**
39      * Error indicating that too many sync operation is ongoing, caller should try again after
40      * some time.
41      */
42     public static final int SYNC_OP_LIMIT_TRY_AGAIN = -1;
43 
44     // These are the same values as defined in VHAL interface.
45     private static final int VEHICLE_PROPERTY_GROUP_MASK = 0xf0000000;
46     private static final int VEHICLE_PROPERTY_GROUP_VENDOR = 0x20000000;
47     private static final int VEHICLE_PROPERTY_GROUP_BACKPORTED = 0x30000000;
48 
49     /**
50      * CarPropertyHelper only contains static fields and methods and must never be instantiated.
51      */
52     @ExcludeFromCodeCoverageGeneratedReport(reason = PRIVATE_CONSTRUCTOR)
CarPropertyHelper()53     private CarPropertyHelper() {
54         throw new UnsupportedOperationException("Must never be called");
55     }
56 
57     /**
58      * Returns whether the property ID is supported by the current Car Service version.
59      */
isSupported(int propertyId)60     public static boolean isSupported(int propertyId) {
61         return isSystemProperty(propertyId) || isVendorOrBackportedProperty(propertyId);
62     }
63 
64     /**
65      * Gets a user-friendly representation of a list of properties.
66      */
propertyIdsToString(Collection<Integer> propertyIds)67     public static String propertyIdsToString(Collection<Integer> propertyIds) {
68         var sj = new StringJoiner(", ", "[", "]");
69         for (int propertyId : propertyIds) {
70             sj.add(toDebugString(propertyId));
71         }
72         return sj.toString();
73     }
74 
75     /**
76      * Gets a user-friendly representation of a list of properties.
77      */
propertyIdsToString(int[] propertyIds)78     public static String propertyIdsToString(int[] propertyIds) {
79         var sj = new StringJoiner(", ", "[", "]");
80         for (int propertyId : propertyIds) {
81             sj.add(toDebugString(propertyId));
82         }
83         return sj.toString();
84     }
85 
86     /**
87      * Returns whether the property ID is defined as a system property.
88      */
isSystemProperty(int propertyId)89     public static boolean isSystemProperty(int propertyId) {
90         return propertyId != VehiclePropertyIds.INVALID && isDefined(propertyId);
91     }
92 
93     /**
94      * Returns whether the property ID is defined as a vendor property or a backported property.
95      */
isVendorOrBackportedProperty(int propertyId)96     public static boolean isVendorOrBackportedProperty(int propertyId) {
97         return isVendorProperty(propertyId) || isBackportedProperty(propertyId);
98     }
99 
100     /**
101      * Returns whether the property ID is defined as a vendor property.
102      */
isVendorProperty(int propertyId)103     public static boolean isVendorProperty(int propertyId) {
104         return (propertyId & VEHICLE_PROPERTY_GROUP_MASK) == VEHICLE_PROPERTY_GROUP_VENDOR;
105     }
106 
107     /**
108      * Returns whether the property ID is defined as a backported property.
109      */
isBackportedProperty(int propertyId)110     public static boolean isBackportedProperty(int propertyId) {
111         return (propertyId & VEHICLE_PROPERTY_GROUP_MASK) == VEHICLE_PROPERTY_GROUP_BACKPORTED;
112     }
113 
114     /**
115      * Gets the default value for a {@link CarPropertyValue} class type.
116      */
getDefaultValue(Class<T> clazz)117     public static <T> T getDefaultValue(Class<T> clazz) {
118         if (clazz.equals(Boolean.class)) {
119             return (T) Boolean.FALSE;
120         }
121         if (clazz.equals(Integer.class)) {
122             return (T) Integer.valueOf(0);
123         }
124         if (clazz.equals(Long.class)) {
125             return (T) Long.valueOf(0);
126         }
127         if (clazz.equals(Float.class)) {
128             return (T) Float.valueOf(0f);
129         }
130         if (clazz.equals(Integer[].class)) {
131             return (T) new Integer[0];
132         }
133         if (clazz.equals(Long[].class)) {
134             return (T) new Long[0];
135         }
136         if (clazz.equals(Float[].class)) {
137             return (T) new Float[0];
138         }
139         if (clazz.equals(byte[].class)) {
140             return (T) EMPTY_BYTE_ARRAY;
141         }
142         if (clazz.equals(Object[].class)) {
143             return (T) new Object[0];
144         }
145         if (clazz.equals(String.class)) {
146             return (T) "";
147         }
148         throw new IllegalArgumentException("Unexpected class: " + clazz);
149     }
150 }
151