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