• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static android.hardware.Sensor.REPORTING_MODE_CONTINUOUS;
21 import static android.hardware.Sensor.REPORTING_MODE_ONE_SHOT;
22 import static android.hardware.Sensor.REPORTING_MODE_ON_CHANGE;
23 import static android.hardware.Sensor.REPORTING_MODE_SPECIAL_TRIGGER;
24 
25 import android.annotation.FlaggedApi;
26 import android.annotation.IntDef;
27 import android.annotation.IntRange;
28 import android.annotation.NonNull;
29 import android.annotation.Nullable;
30 import android.annotation.SuppressLint;
31 import android.annotation.SystemApi;
32 import android.annotation.TestApi;
33 import android.companion.virtualdevice.flags.Flags;
34 import android.hardware.Sensor;
35 import android.hardware.SensorDirectChannel;
36 import android.os.Parcel;
37 import android.os.Parcelable;
38 
39 import java.lang.annotation.Retention;
40 import java.lang.annotation.RetentionPolicy;
41 import java.util.Objects;
42 
43 
44 /**
45  * Configuration for creation of a virtual sensor.
46  *
47  * @see VirtualSensor
48  *
49  * @hide
50  */
51 @SystemApi
52 public final class VirtualSensorConfig implements Parcelable {
53     private static final String TAG = "VirtualSensorConfig";
54 
55     // Defined in sensors.h
56     private static final int FLAG_WAKE_UP_SENSOR = 1;
57 
58     // Mask for the reporting mode, bit 2, 3, 4.
59     private static final int REPORTING_MODE_MASK = 0xE;
60     private static final int REPORTING_MODE_SHIFT = 1;
61 
62     // Mask for indication bit of sensor additional information support, bit 6.
63     static final int ADDITIONAL_INFO_MASK = 0x40;
64 
65     // Mask for direct mode highest rate level, bit 7, 8, 9.
66     private static final int DIRECT_REPORT_MASK = 0x380;
67     private static final int DIRECT_REPORT_SHIFT = 7;
68 
69 
70     // Mask for supported direct channel, bit 10, 11
71     private static final int DIRECT_CHANNEL_SHIFT = 10;
72 
73     private final int mType;
74     @NonNull
75     private final String mName;
76     @Nullable
77     private final String mVendor;
78     private final float mMaximumRange;
79     private final float mResolution;
80     private final float mPower;
81     private final int mMinDelay;
82     private final int mMaxDelay;
83 
84     private final int mFlags;
85 
86     /** @hide */
87     @IntDef(prefix = "REPORTING_MODE_", value = {
88             REPORTING_MODE_CONTINUOUS,
89             REPORTING_MODE_ON_CHANGE,
90             REPORTING_MODE_ONE_SHOT,
91             REPORTING_MODE_SPECIAL_TRIGGER
92     })
93 
94     @Retention(RetentionPolicy.SOURCE)
95     public @interface ReportingMode {}
96 
VirtualSensorConfig(int type, @NonNull String name, @Nullable String vendor, float maximumRange, float resolution, float power, int minDelay, int maxDelay, int flags)97     private VirtualSensorConfig(int type, @NonNull String name, @Nullable String vendor,
98             float maximumRange, float resolution, float power, int minDelay, int maxDelay,
99             int flags) {
100         mType = type;
101         mName = name;
102         mVendor = vendor;
103         mMaximumRange = maximumRange;
104         mResolution = resolution;
105         mPower = power;
106         mMinDelay = minDelay;
107         mMaxDelay = maxDelay;
108         mFlags = flags;
109     }
110 
VirtualSensorConfig(@onNull Parcel parcel)111     private VirtualSensorConfig(@NonNull Parcel parcel) {
112         mType = parcel.readInt();
113         mName = parcel.readString8();
114         mVendor = parcel.readString8();
115         mMaximumRange = parcel.readFloat();
116         mResolution = parcel.readFloat();
117         mPower = parcel.readFloat();
118         mMinDelay = parcel.readInt();
119         mMaxDelay = parcel.readInt();
120         mFlags = parcel.readInt();
121     }
122 
123     @Override
describeContents()124     public int describeContents() {
125         return 0;
126     }
127 
128     @Override
writeToParcel(@onNull Parcel parcel, int flags)129     public void writeToParcel(@NonNull Parcel parcel, int flags) {
130         parcel.writeInt(mType);
131         parcel.writeString8(mName);
132         parcel.writeString8(mVendor);
133         parcel.writeFloat(mMaximumRange);
134         parcel.writeFloat(mResolution);
135         parcel.writeFloat(mPower);
136         parcel.writeInt(mMinDelay);
137         parcel.writeInt(mMaxDelay);
138         parcel.writeInt(mFlags);
139     }
140 
141     @Override
toString()142     public String toString() {
143         return "VirtualSensorConfig{" + "mType=" + mType + ", mName='" + mName + '\'' + '}';
144     }
145 
146     /**
147      * Returns the type of the sensor.
148      *
149      * @see Sensor#getType()
150      * @see <a href="https://source.android.com/devices/sensors/sensor-types">Sensor types</a>
151      */
getType()152     public int getType() {
153         return mType;
154     }
155 
156     /**
157      * Returns the name of the sensor, which must be unique per sensor type for each virtual device.
158      */
159     @NonNull
getName()160     public String getName() {
161         return mName;
162     }
163 
164     /**
165      * Returns the vendor string of the sensor.
166      *
167      * @see Builder#setVendor
168      */
169     @Nullable
getVendor()170     public String getVendor() {
171         return mVendor;
172     }
173 
174     /**
175      * Returns the maximum range of the sensor in the sensor's unit.
176      *
177      * @see Sensor#getMaximumRange
178      */
getMaximumRange()179     public float getMaximumRange() {
180         return mMaximumRange;
181     }
182 
183     /**
184      * Returns the resolution of the sensor in the sensor's unit.
185      *
186      * @see Sensor#getResolution
187      */
getResolution()188     public float getResolution() {
189         return mResolution;
190     }
191 
192     /**
193      * Returns the power in mA used by this sensor while in use.
194      *
195      * @see Sensor#getPower
196      */
getPower()197     public float getPower() {
198         return mPower;
199     }
200 
201     /**
202      * Returns the minimum delay allowed between two events in microseconds, or zero depending on
203      * the sensor type.
204      *
205      * @see Sensor#getMinDelay
206      */
getMinDelay()207     public int getMinDelay() {
208         return mMinDelay;
209     }
210 
211     /**
212      * Returns the maximum delay between two sensor events in microseconds.
213      *
214      * @see Sensor#getMaxDelay
215      */
getMaxDelay()216     public int getMaxDelay() {
217         return mMaxDelay;
218     }
219 
220     /**
221      * Returns the highest supported direct report mode rate level of the sensor.
222      *
223      * @see Sensor#getHighestDirectReportRateLevel()
224      */
225     @SensorDirectChannel.RateLevel
getHighestDirectReportRateLevel()226     public int getHighestDirectReportRateLevel() {
227         int rateLevel = ((mFlags & DIRECT_REPORT_MASK) >> DIRECT_REPORT_SHIFT);
228         return Math.min(rateLevel, SensorDirectChannel.RATE_VERY_FAST);
229     }
230 
231     /**
232      * Returns a combination of all supported direct channel types.
233      *
234      * @see Builder#setDirectChannelTypesSupported(int)
235      * @see Sensor#isDirectChannelTypeSupported(int)
236      */
getDirectChannelTypesSupported()237     public @SensorDirectChannel.MemoryType int getDirectChannelTypesSupported() {
238         int memoryTypes = 0;
239         if ((mFlags & (1 << DIRECT_CHANNEL_SHIFT)) > 0) {
240             memoryTypes |= SensorDirectChannel.TYPE_MEMORY_FILE;
241         }
242         if ((mFlags & (1 << (DIRECT_CHANNEL_SHIFT + 1))) > 0) {
243             memoryTypes |= SensorDirectChannel.TYPE_HARDWARE_BUFFER;
244         }
245         return memoryTypes;
246     }
247 
248     /**
249      * Returns whether the sensor is a wake-up sensor.
250      *
251      * @see Builder#setWakeUpSensor(boolean)
252      * @see Sensor#isWakeUpSensor()
253      */
254     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
isWakeUpSensor()255     public boolean isWakeUpSensor() {
256         return (mFlags & FLAG_WAKE_UP_SENSOR) > 0;
257     }
258 
259     /**
260      * Returns whether the sensor supports additional information.
261      *
262      * @see Builder#setAdditionalInfoSupported(boolean)
263      * @see Sensor#isAdditionalInfoSupported()
264      * @see android.hardware.SensorAdditionalInfo
265      */
266     @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
isAdditionalInfoSupported()267     public boolean isAdditionalInfoSupported() {
268         return (mFlags & ADDITIONAL_INFO_MASK) > 0;
269     }
270 
271     /**
272      * Returns the reporting mode of this sensor.
273      *
274      * @see Builder#setReportingMode(int)
275      * @see Sensor#getReportingMode()
276      */
277     @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
getReportingMode()278     public @ReportingMode int getReportingMode() {
279         return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
280     }
281 
282     /**
283      * Returns the sensor flags.
284      *
285      * @hide
286      */
287     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
288     @TestApi
getFlags()289     public int getFlags() {
290         return mFlags;
291     }
292 
293     /**
294      * Builder for {@link VirtualSensorConfig}.
295      */
296     public static final class Builder {
297 
298         private static final int FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED =
299                 1 << DIRECT_CHANNEL_SHIFT;
300         private final int mType;
301         @NonNull
302         private final String mName;
303         @Nullable
304         private String mVendor;
305         private float mMaximumRange;
306         private float mResolution;
307         private float mPower;
308         private int mMinDelay;
309         private int mMaxDelay;
310         private int mFlags;
311         @SensorDirectChannel.RateLevel
312         int mHighestDirectReportRateLevel;
313 
314         /**
315          * Creates a new builder.
316          *
317          * @param type The type of the sensor, matching {@link Sensor#getType}.
318          * @param name The name of the sensor. Must be unique among all sensors with the same type
319          *   that belong to the same virtual device.
320          */
Builder(@ntRangefrom = 1) int type, @NonNull String name)321         public Builder(@IntRange(from = 1) int type, @NonNull String name) {
322             if (type <= 0) {
323                 throw new IllegalArgumentException("Virtual sensor type must be positive");
324             }
325             mType = type;
326             mName = Objects.requireNonNull(name);
327         }
328 
329         /**
330          * Creates a new {@link VirtualSensorConfig}.
331          */
332         @NonNull
build()333         public VirtualSensorConfig build() {
334             if (mHighestDirectReportRateLevel > 0) {
335                 if ((mFlags & FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED) == 0) {
336                     throw new IllegalArgumentException("Setting direct channel type is required "
337                             + "for sensors with direct channel support.");
338                 }
339                 mFlags |= mHighestDirectReportRateLevel << DIRECT_REPORT_SHIFT;
340             }
341             if ((mFlags & FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED) > 0
342                     && mHighestDirectReportRateLevel == 0) {
343                 throw new IllegalArgumentException("Highest direct report rate level is "
344                         + "required for sensors with direct channel support.");
345             }
346             return new VirtualSensorConfig(mType, mName, mVendor, mMaximumRange, mResolution,
347                     mPower, mMinDelay, mMaxDelay, mFlags);
348         }
349 
350         /**
351          * Sets the vendor string of the sensor.
352          */
353         @NonNull
setVendor(@ullable String vendor)354         public VirtualSensorConfig.Builder setVendor(@Nullable String vendor) {
355             mVendor = vendor;
356             return this;
357         }
358 
359         /**
360          * Sets the maximum range of the sensor in the sensor's unit.
361          *
362          * @see Sensor#getMaximumRange
363          */
364         @NonNull
setMaximumRange(float maximumRange)365         public VirtualSensorConfig.Builder setMaximumRange(float maximumRange) {
366             mMaximumRange = maximumRange;
367             return this;
368         }
369 
370         /**
371          * Sets the resolution of the sensor in the sensor's unit.
372          *
373          * @see Sensor#getResolution
374          */
375         @NonNull
setResolution(float resolution)376         public VirtualSensorConfig.Builder setResolution(float resolution) {
377             mResolution = resolution;
378             return this;
379         }
380 
381         /**
382          * Sets the power in mA used by this sensor while in use.
383          *
384          * @see Sensor#getPower
385          */
386         @NonNull
setPower(float power)387         public VirtualSensorConfig.Builder setPower(float power) {
388             mPower = power;
389             return this;
390         }
391 
392         /**
393          * Sets the minimum delay allowed between two events in microseconds.
394          *
395          * @see Sensor#getMinDelay
396          */
397         @NonNull
setMinDelay(int minDelay)398         public VirtualSensorConfig.Builder setMinDelay(int minDelay) {
399             mMinDelay = minDelay;
400             return this;
401         }
402 
403         /**
404          * Sets the maximum delay between two sensor events in microseconds.
405          *
406          * @see Sensor#getMaxDelay
407          */
408         @NonNull
setMaxDelay(int maxDelay)409         public VirtualSensorConfig.Builder setMaxDelay(int maxDelay) {
410             mMaxDelay = maxDelay;
411             return this;
412         }
413 
414         /**
415          * Sets the highest supported rate level for direct sensor report.
416          *
417          * @see VirtualSensorConfig#getHighestDirectReportRateLevel()
418          */
419         @NonNull
setHighestDirectReportRateLevel( @ensorDirectChannel.RateLevel int rateLevel)420         public VirtualSensorConfig.Builder setHighestDirectReportRateLevel(
421                 @SensorDirectChannel.RateLevel int rateLevel) {
422             mHighestDirectReportRateLevel = rateLevel;
423             return this;
424         }
425 
426         /**
427          * Sets whether direct sensor channel of the given types is supported.
428          *
429          * @param memoryTypes A combination of {@link SensorDirectChannel.MemoryType} flags
430          *   indicating the types of shared memory supported for creating direct channels. Only
431          *   {@link SensorDirectChannel#TYPE_MEMORY_FILE} direct channels may be supported for
432          *   virtual sensors.
433          * @throws IllegalArgumentException if {@link SensorDirectChannel#TYPE_HARDWARE_BUFFER} is
434          *   set to be supported.
435          */
436         @NonNull
setDirectChannelTypesSupported( @ensorDirectChannel.MemoryType int memoryTypes)437         public VirtualSensorConfig.Builder setDirectChannelTypesSupported(
438                 @SensorDirectChannel.MemoryType int memoryTypes) {
439             if ((memoryTypes & SensorDirectChannel.TYPE_MEMORY_FILE) > 0) {
440                 mFlags |= FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED;
441             } else {
442                 mFlags &= ~FLAG_MEMORY_FILE_DIRECT_CHANNEL_SUPPORTED;
443             }
444             if ((memoryTypes & ~SensorDirectChannel.TYPE_MEMORY_FILE) > 0) {
445                 throw new IllegalArgumentException(
446                         "Only TYPE_MEMORY_FILE direct channels can be supported for virtual "
447                                 + "sensors.");
448             }
449             return this;
450         }
451 
452         /**
453          * Sets whether this sensor is a wake up sensor.
454          *
455          * @see Sensor#isWakeUpSensor()
456          */
457         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
458         @NonNull
setWakeUpSensor(boolean wakeUpSensor)459         public VirtualSensorConfig.Builder setWakeUpSensor(boolean wakeUpSensor) {
460             if (wakeUpSensor) {
461                 mFlags |= FLAG_WAKE_UP_SENSOR;
462             } else {
463                 mFlags &= ~FLAG_WAKE_UP_SENSOR;
464             }
465             return this;
466         }
467 
468         /**
469          * Sets whether this sensor supports sensor additional information.
470          *
471          * @see Sensor#isAdditionalInfoSupported()
472          * @see android.hardware.SensorAdditionalInfo
473          * @see VirtualSensorAdditionalInfo
474          */
475         @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
476         @NonNull
setAdditionalInfoSupported( boolean additionalInfoSupported)477         public VirtualSensorConfig.Builder setAdditionalInfoSupported(
478                 boolean additionalInfoSupported) {
479             if (additionalInfoSupported) {
480                 mFlags |= ADDITIONAL_INFO_MASK;
481             } else {
482                 mFlags &= ~ADDITIONAL_INFO_MASK;
483             }
484             return this;
485         }
486 
487         /**
488          * Sets the reporting mode of this sensor.
489          *
490          * @throws IllegalArgumentException if the reporting mode is not one of
491          *   {@link Sensor#REPORTING_MODE_CONTINUOUS}, {@link Sensor#REPORTING_MODE_ON_CHANGE},
492          *   {@link Sensor#REPORTING_MODE_ONE_SHOT}, or
493          *   {@link Sensor#REPORTING_MODE_SPECIAL_TRIGGER}.
494          *
495          * @see Sensor#getReportingMode()
496          */
497         @FlaggedApi(Flags.FLAG_DEVICE_AWARE_DISPLAY_POWER)
498         @NonNull
setReportingMode(@eportingMode int reportingMode)499         public VirtualSensorConfig.Builder setReportingMode(@ReportingMode int reportingMode) {
500             if (reportingMode != REPORTING_MODE_CONTINUOUS
501                     && reportingMode != REPORTING_MODE_ON_CHANGE
502                     && reportingMode != REPORTING_MODE_ONE_SHOT
503                     && reportingMode != REPORTING_MODE_SPECIAL_TRIGGER) {
504                 throw new IllegalArgumentException("Invalid reporting mode: " + reportingMode);
505             }
506             mFlags |= reportingMode << REPORTING_MODE_SHIFT;
507             return this;
508         }
509     }
510 
511     @NonNull
512     public static final Parcelable.Creator<VirtualSensorConfig> CREATOR =
513             new Parcelable.Creator<>() {
514                 public VirtualSensorConfig createFromParcel(Parcel source) {
515                     return new VirtualSensorConfig(source);
516                 }
517 
518                 public VirtualSensorConfig[] newArray(int size) {
519                     return new VirtualSensorConfig[size];
520                 }
521             };
522 }
523