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 android.companion.virtual.sensor;
18 
19 
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.annotation.Nullable;
23 import android.annotation.SystemApi;
24 import android.hardware.Sensor;
25 import android.hardware.SensorDirectChannel;
26 import android.os.Parcel;
27 import android.os.Parcelable;
28 
29 import java.util.Objects;
30 
31 
32 /**
33  * Configuration for creation of a virtual sensor.
34  *
35  * @see VirtualSensor
36  *
37  * @hide
38  */
39 @SystemApi
40 public final class VirtualSensorConfig implements Parcelable {
41     private static final String TAG = "VirtualSensorConfig";
42 
43     // Mask for direct mode highest rate level, bit 7, 8, 9.
44     private static final int DIRECT_REPORT_MASK = 0x380;
45     private static final int DIRECT_REPORT_SHIFT = 7;
46 
47     // Mask for supported direct channel, bit 10, 11
48     private static final int DIRECT_CHANNEL_SHIFT = 10;
49 
50     private final int mType;
51     @NonNull
52     private final String mName;
53     @Nullable
54     private final String mVendor;
55     private final float mMaximumRange;
56     private final float mResolution;
57     private final float mPower;
58     private final int mMinDelay;
59     private final int mMaxDelay;
60 
61     private final int mFlags;
62 
VirtualSensorConfig(int type, @NonNull String name, @Nullable String vendor, float maximumRange, float resolution, float power, int minDelay, int maxDelay, int flags)63     private VirtualSensorConfig(int type, @NonNull String name, @Nullable String vendor,
64             float maximumRange, float resolution, float power, int minDelay, int maxDelay,
65             int flags) {
66         mType = type;
67         mName = name;
68         mVendor = vendor;
69         mMaximumRange = maximumRange;
70         mResolution = resolution;
71         mPower = power;
72         mMinDelay = minDelay;
73         mMaxDelay = maxDelay;
74         mFlags = flags;
75     }
76 
VirtualSensorConfig(@onNull Parcel parcel)77     private VirtualSensorConfig(@NonNull Parcel parcel) {
78         mType = parcel.readInt();
79         mName = parcel.readString8();
80         mVendor = parcel.readString8();
81         mMaximumRange = parcel.readFloat();
82         mResolution = parcel.readFloat();
83         mPower = parcel.readFloat();
84         mMinDelay = parcel.readInt();
85         mMaxDelay = parcel.readInt();
86         mFlags = parcel.readInt();
87     }
88 
89     @Override
describeContents()90     public int describeContents() {
91         return 0;
92     }
93 
94     @Override
writeToParcel(@onNull Parcel parcel, int flags)95     public void writeToParcel(@NonNull Parcel parcel, int flags) {
96         parcel.writeInt(mType);
97         parcel.writeString8(mName);
98         parcel.writeString8(mVendor);
99         parcel.writeFloat(mMaximumRange);
100         parcel.writeFloat(mResolution);
101         parcel.writeFloat(mPower);
102         parcel.writeInt(mMinDelay);
103         parcel.writeInt(mMaxDelay);
104         parcel.writeInt(mFlags);
105     }
106 
107     /**
108      * Returns the type of the sensor.
109      *
110      * @see Sensor#getType()
111      * @see <a href="https://source.android.com/devices/sensors/sensor-types">Sensor types</a>
112      */
getType()113     public int getType() {
114         return mType;
115     }
116 
117     /**
118      * Returns the name of the sensor, which must be unique per sensor type for each virtual device.
119      */
120     @NonNull
getName()121     public String getName() {
122         return mName;
123     }
124 
125     /**
126      * Returns the vendor string of the sensor.
127      *
128      * @see Builder#setVendor
129      */
130     @Nullable
getVendor()131     public String getVendor() {
132         return mVendor;
133     }
134 
135     /**
136      * Returns the maximum range of the sensor in the sensor's unit.
137      *
138      * @see Sensor#getMaximumRange
139      */
getMaximumRange()140     public float getMaximumRange() {
141         return mMaximumRange;
142     }
143 
144     /**
145      * Returns the resolution of the sensor in the sensor's unit.
146      *
147      * @see Sensor#getResolution
148      */
getResolution()149     public float getResolution() {
150         return mResolution;
151     }
152 
153     /**
154      * Returns the power in mA used by this sensor while in use.
155      *
156      * @see Sensor#getPower
157      */
getPower()158     public float getPower() {
159         return mPower;
160     }
161 
162     /**
163      * Returns the minimum delay allowed between two events in microseconds, or zero depending on
164      * the sensor type.
165      *
166      * @see Sensor#getMinDelay
167      */
getMinDelay()168     public int getMinDelay() {
169         return mMinDelay;
170     }
171 
172     /**
173      * Returns the maximum delay between two sensor events in microseconds.
174      *
175      * @see Sensor#getMaxDelay
176      */
getMaxDelay()177     public int getMaxDelay() {
178         return mMaxDelay;
179     }
180 
181     /**
182      * Returns the highest supported direct report mode rate level of the sensor.
183      *
184      * @see Sensor#getHighestDirectReportRateLevel()
185      */
186     @SensorDirectChannel.RateLevel
getHighestDirectReportRateLevel()187     public int getHighestDirectReportRateLevel() {
188         int rateLevel = ((mFlags & DIRECT_REPORT_MASK) >> DIRECT_REPORT_SHIFT);
189         return rateLevel <= SensorDirectChannel.RATE_VERY_FAST
190                 ? rateLevel : SensorDirectChannel.RATE_VERY_FAST;
191     }
192 
193     /**
194      * Returns a combination of all supported direct channel types.
195      *
196      * @see Builder#setDirectChannelTypesSupported(int)
197      * @see Sensor#isDirectChannelTypeSupported(int)
198      */
getDirectChannelTypesSupported()199     public @SensorDirectChannel.MemoryType int getDirectChannelTypesSupported() {
200         int memoryTypes = 0;
201         if ((mFlags & (1 << DIRECT_CHANNEL_SHIFT)) > 0) {
202             memoryTypes |= SensorDirectChannel.TYPE_MEMORY_FILE;
203         }
204         if ((mFlags & (1 << (DIRECT_CHANNEL_SHIFT + 1))) > 0) {
205             memoryTypes |= SensorDirectChannel.TYPE_HARDWARE_BUFFER;
206         }
207         return memoryTypes;
208     }
209 
210     /**
211      * Returns the sensor flags.
212      *
213      * @hide
214      */
getFlags()215     public int getFlags() {
216         return mFlags;
217     }
218 
219     /**
220      * Builder for {@link VirtualSensorConfig}.
221      */
222     public static final class Builder {
223 
224         private static final int FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED =
225                 1 << DIRECT_CHANNEL_SHIFT;
226         private final int mType;
227         @NonNull
228         private final String mName;
229         @Nullable
230         private String mVendor;
231         private float mMaximumRange;
232         private float mResolution;
233         private float mPower;
234         private int mMinDelay;
235         private int mMaxDelay;
236         private int mFlags;
237         @SensorDirectChannel.RateLevel
238         int mHighestDirectReportRateLevel;
239 
240         /**
241          * Creates a new builder.
242          *
243          * @param type The type of the sensor, matching {@link Sensor#getType}.
244          * @param name The name of the sensor. Must be unique among all sensors with the same type
245          *   that belong to the same virtual device.
246          */
Builder(@ntRangefrom = 1) int type, @NonNull String name)247         public Builder(@IntRange(from = 1) int type, @NonNull String name) {
248             if (type <= 0) {
249                 throw new IllegalArgumentException("Virtual sensor type must be positive");
250             }
251             mType = type;
252             mName = Objects.requireNonNull(name);
253         }
254 
255         /**
256          * Creates a new {@link VirtualSensorConfig}.
257          */
258         @NonNull
build()259         public VirtualSensorConfig build() {
260             if (mHighestDirectReportRateLevel > 0) {
261                 if ((mFlags & FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED) == 0) {
262                     throw new IllegalArgumentException("Setting direct channel type is required "
263                             + "for sensors with direct channel support.");
264                 }
265                 mFlags |= mHighestDirectReportRateLevel << DIRECT_REPORT_SHIFT;
266             }
267             if ((mFlags & FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED) > 0
268                     && mHighestDirectReportRateLevel == 0) {
269                 throw new IllegalArgumentException("Highest direct report rate level is "
270                         + "required for sensors with direct channel support.");
271             }
272             return new VirtualSensorConfig(mType, mName, mVendor, mMaximumRange, mResolution,
273                     mPower, mMinDelay, mMaxDelay, mFlags);
274         }
275 
276         /**
277          * Sets the vendor string of the sensor.
278          */
279         @NonNull
setVendor(@ullable String vendor)280         public VirtualSensorConfig.Builder setVendor(@Nullable String vendor) {
281             mVendor = vendor;
282             return this;
283         }
284 
285         /**
286          * Sets the maximum range of the sensor in the sensor's unit.
287          *
288          * @see Sensor#getMaximumRange
289          */
290         @NonNull
setMaximumRange(float maximumRange)291         public VirtualSensorConfig.Builder setMaximumRange(float maximumRange) {
292             mMaximumRange = maximumRange;
293             return this;
294         }
295 
296         /**
297          * Sets the resolution of the sensor in the sensor's unit.
298          *
299          * @see Sensor#getResolution
300          */
301         @NonNull
setResolution(float resolution)302         public VirtualSensorConfig.Builder setResolution(float resolution) {
303             mResolution = resolution;
304             return this;
305         }
306 
307         /**
308          * Sets the power in mA used by this sensor while in use.
309          *
310          * @see Sensor#getPower
311          */
312         @NonNull
setPower(float power)313         public VirtualSensorConfig.Builder setPower(float power) {
314             mPower = power;
315             return this;
316         }
317 
318         /**
319          * Sets the minimum delay allowed between two events in microseconds.
320          *
321          * @see Sensor#getMinDelay
322          */
323         @NonNull
setMinDelay(int minDelay)324         public VirtualSensorConfig.Builder setMinDelay(int minDelay) {
325             mMinDelay = minDelay;
326             return this;
327         }
328 
329         /**
330          * Sets the maximum delay between two sensor events in microseconds.
331          *
332          * @see Sensor#getMaxDelay
333          */
334         @NonNull
setMaxDelay(int maxDelay)335         public VirtualSensorConfig.Builder setMaxDelay(int maxDelay) {
336             mMaxDelay = maxDelay;
337             return this;
338         }
339 
340         /**
341          * Sets the highest supported rate level for direct sensor report.
342          *
343          * @see VirtualSensorConfig#getHighestDirectReportRateLevel()
344          */
345         @NonNull
setHighestDirectReportRateLevel( @ensorDirectChannel.RateLevel int rateLevel)346         public VirtualSensorConfig.Builder setHighestDirectReportRateLevel(
347                 @SensorDirectChannel.RateLevel int rateLevel) {
348             mHighestDirectReportRateLevel = rateLevel;
349             return this;
350         }
351 
352         /**
353          * Sets whether direct sensor channel of the given types is supported.
354          *
355          * @param memoryTypes A combination of {@link SensorDirectChannel.MemoryType} flags
356          *   indicating the types of shared memory supported for creating direct channels. Only
357          *   {@link SensorDirectChannel#TYPE_MEMORY_FILE} direct channels may be supported for
358          *   virtual sensors.
359          * @throws IllegalArgumentException if {@link SensorDirectChannel#TYPE_HARDWARE_BUFFER} is
360          *   set to be supported.
361          */
362         @NonNull
setDirectChannelTypesSupported( @ensorDirectChannel.MemoryType int memoryTypes)363         public VirtualSensorConfig.Builder setDirectChannelTypesSupported(
364                 @SensorDirectChannel.MemoryType int memoryTypes) {
365             if ((memoryTypes & SensorDirectChannel.TYPE_MEMORY_FILE) > 0) {
366                 mFlags |= FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED;
367             } else {
368                 mFlags &= ~FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED;
369             }
370             if ((memoryTypes & ~SensorDirectChannel.TYPE_MEMORY_FILE) > 0) {
371                 throw new IllegalArgumentException(
372                         "Only TYPE_MEMORY_FILE direct channels can be supported for virtual "
373                                 + "sensors.");
374             }
375             return this;
376         }
377     }
378 
379     @NonNull
380     public static final Parcelable.Creator<VirtualSensorConfig> CREATOR =
381             new Parcelable.Creator<>() {
382                 public VirtualSensorConfig createFromParcel(Parcel source) {
383                     return new VirtualSensorConfig(source);
384                 }
385 
386                 public VirtualSensorConfig[] newArray(int size) {
387                     return new VirtualSensorConfig[size];
388                 }
389             };
390 }
391