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