Skip to content

Commit

Permalink
Merge pull request #65 from mutualmobile/development
Browse files Browse the repository at this point in the history
Version 0.3.0 Changes
  • Loading branch information
shubhamsinghmutualmobile authored May 20, 2023
2 parents 4a766f1 + a95cecc commit 2430cb8
Show file tree
Hide file tree
Showing 66 changed files with 2,108 additions and 262 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,11 @@ Proximity | ✅️️ | rememberProximitySensorState()
Gravity | ✅️ | rememberGravitySensorState()
Linear Acceleration | ✅️ | rememberLinearAccelerationSensorState()
Rotation Vector | ✅️️ | rememberRotationVectorSensorState()
Relative Humidity | ⚠️ | WIP
Relative Humidity | ✅️️ | rememberRelativeHumiditySensorState()
Ambient Temperature | ✅️ | rememberAmbientTemperatureSensorState()
Magnetic Field (Uncalibrated) | ✅️️ | rememberUncalibratedMagneticFieldSensorState()
GameRotation Vector | ✅️ | rememberGameRotationVectorSensorState()
Gyroscope (Uncalibrated) | ️ | WIP
Gyroscope (Uncalibrated) | ️ | rememberUncalibratedGyroscopeSensorState()
Significant Motion | — | N/A
Step Detector | ✅️ | rememberStepDetectorSensorState()
Step Counter | ✅️ | rememberStepCounterSensorState()
Expand All @@ -100,15 +100,15 @@ Pose6DOF | — | N/A
Stationary Detect | ⚠️ | WIP
Motion Detect | ⚠️ | WIP
Heart Beat | — | N/A
Low Latency Off-Body Detect | | N/A
Accelerometer (Uncalibrated) | ️ | WIP
Low Latency Off-Body Detect | ✅️ | rememberLowLatencyOffBodyDetectSensorState()
Accelerometer (Uncalibrated) | ️ | rememberUncalibratedAccelerometerSensorState()
Hinge Angle | ✅️ | rememberHingeAngleSensorState()
Head Tracker | | N/A
Accelerometer Limited Axes | ️ | WIP
Head Tracker | ✅️ | rememberHeadTrackerSensorState()
Accelerometer Limited Axes | ️ | rememberLimitedAxesAccelerometerSensorState()
Gyroscope Limited Axes | ✅️️ | rememberLimitedAxesGyroscopeSensorState()
Accelerometer Limited Axes (Uncalibrated) | ⚠️ | WIP
Accelerometer Limited Axes (Uncalibrated) | | rememberUncalibratedLimitedAxesAccelerometerSensorState()
Gyroscope Limited Axes (Uncalibrated) | — | N/A
Heading | ⚠️ | WIP
Heading | | rememberHeadingSensorState()
All | — | N/A

## License 🔖
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.mutualmobile.composesensors

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

/**
* The HeadTracker sensor measures the orientation of a user's head relative to an arbitrary reference frame, as well as the rate of rotation.
* @param xRotation X component of Euler vector representing rotation. Defaults to 0f.
* @param yRotation Y component of Euler vector representing rotation. Defaults to 0f.
* @param zRotation Z component of Euler vector representing rotation. Defaults to 0f.
* @param xAngularVelocity X component of Euler vector representing angular velocity (if supported, otherwise 0). Defaults to 0f.
* @param yAngularVelocity Y component of Euler vector representing angular velocity (if supported, otherwise 0). Defaults to 0f.
* @param zAngularVelocity Z component of Euler vector representing angular velocity (if supported, otherwise 0). Defaults to 0f.
* @param isAvailable Whether the current device has a gyroscope sensor. Defaults to false.
* @param accuracy Accuracy factor of the gyroscope sensor. Defaults to 0.
**/
@Immutable
class HeadTrackerSensorState internal constructor(
val xRotation: Float = 0f,
val yRotation: Float = 0f,
val zRotation: Float = 0f,
val xAngularVelocity: Float = 0f,
val yAngularVelocity: Float = 0f,
val zAngularVelocity: Float = 0f,
val isAvailable: Boolean = false,
val accuracy: Int = 0
) {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

other as HeadTrackerSensorState

if (xRotation != other.xRotation) return false
if (yRotation != other.yRotation) return false
if (zRotation != other.zRotation) return false
if (xAngularVelocity != other.xAngularVelocity) return false
if (yAngularVelocity != other.yAngularVelocity) return false
if (zAngularVelocity != other.zAngularVelocity) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false

return true
}

override fun hashCode(): Int {
var result = xRotation.hashCode()
result = 31 * result + yRotation.hashCode()
result = 31 * result + zRotation.hashCode()
result = 31 * result + xAngularVelocity.hashCode()
result = 31 * result + yAngularVelocity.hashCode()
result = 31 * result + zAngularVelocity.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy
return result
}

override fun toString(): String {
return "HeadTrackerSensorState(xRotation=$xRotation, yRotation=$yRotation, zRotation=$zRotation, xAngularVelocity=$xAngularVelocity, yAngularVelocity=$yAngularVelocity, zAngularVelocity=$zAngularVelocity, isAvailable=$isAvailable, accuracy=$accuracy)"
}
}

/**
* Creates and [remember]s an instance of [HeadTrackerSensorState].
* @param sensorDelay The rate at which the raw sensor data should be received.
* Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@RequiresApi(Build.VERSION_CODES.TIRAMISU)
@Composable
fun rememberHeadTrackerSensorState(
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {}
): HeadTrackerSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.HeadTracker,
sensorDelay = sensorDelay,
onError = onError
)

val headTrackerSensor = remember { mutableStateOf(HeadTrackerSensorState()) }

LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
headTrackerSensor.value = HeadTrackerSensorState(
xRotation = sensorStateValues[0],
yRotation = sensorStateValues[1],
zRotation = sensorStateValues[2],
xAngularVelocity = sensorStateValues[3],
yAngularVelocity = sensorStateValues[4],
zAngularVelocity = sensorStateValues[5],
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy
)
}
})

return headTrackerSensor.value
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package com.mutualmobile.composesensors

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

/**
* Measures a device's heading value in degrees (anti-clockwise),
*
* @param degrees Indicates direction in which the device is pointing
* relative to true north in degrees. Defaults to 0f.
* @param accuracy Indicates the confidence of prediction, under Gaussian
* standard normal distribution. Defaults to 0f.
* @param isAvailable Whether the current device has a heading sensor.
* Defaults to false.
*/
@Immutable
class HeadingSensorState internal constructor(
val degrees: Float = 0f,
val accuracy: Float = 0f,
val isAvailable: Boolean = false
) {
override fun hashCode(): Int {
var result = degrees.hashCode()
result = 31 * result + accuracy.hashCode()
result = 31 * result + isAvailable.hashCode()
return result
}

override fun toString(): String {
return "HeadingSensorState(degrees=$degrees, accuracy=$accuracy, " +
"isAvailable=$isAvailable)"
}

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is HeadingSensorState) return false

if (degrees != other.degrees) return false
if (accuracy != other.accuracy) return false
if (isAvailable != other.isAvailable) return false

return true
}
}

/**
* Creates and [remember]s an instance of [HeadingSensorState].
*
* @param sensorDelay The rate at which the raw sensor data should be
* received. Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@Composable
fun rememberHeadingSensorState(
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {}
): HeadingSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.Heading,
sensorDelay = sensorDelay,
onError = onError
)

val headingSensorState = remember { mutableStateOf(HeadingSensorState()) }

LaunchedEffect(key1 = sensorState, block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
headingSensorState.value = HeadingSensorState(
degrees = sensorStateValues[0],
accuracy = sensorStateValues[1],
isAvailable = sensorState.isAvailable
)
}
})

return headingSensorState.value
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.mutualmobile.composesensors

import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
Expand Down Expand Up @@ -50,6 +52,7 @@ class HingeAngleSensorState internal constructor(
* Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@RequiresApi(Build.VERSION_CODES.R)
@Composable
fun rememberHingeAngleSensorState(
sensorDelay: SensorDelay = SensorDelay.Normal,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.mutualmobile.composesensors

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

/**
* An acceleration sensor determines the acceleration that is applied to a device by measuring the
* forces that are applied to the sensor itself.
* @param xForce Acceleration minus Gx on the x-axis (if supported)
* @param yForce Acceleration minus Gy on the y-axis (if supported)
* @param zForce Acceleration minus Gz on the z-axis (if supported)
* @param xAxisSupported Acceleration supported for x-axis. Defaults to false.
* @param yAxisSupported Acceleration supported for y-axis. Defaults to false.
* @param zAxisSupported Acceleration supported for z-axis. Defaults to false.
* @param isAvailable Whether the current device has an accelerometer with limited axes sensor. Defaults to false.
* @param accuracy Accuracy factor of the accelerometer with limited axes sensor. Defaults to 0.
*/
@Immutable
class LimitedAxesAccelerometerSensorState internal constructor(
val xForce: Float = 0f,
val yForce: Float = 0f,
val zForce: Float = 0f,
val xAxisSupported: Boolean = false,
val yAxisSupported: Boolean = false,
val zAxisSupported: Boolean = false,
val isAvailable: Boolean = false,
val accuracy: Int = 0
) {

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is LimitedAxesAccelerometerSensorState) return false

if (xForce != other.xForce) return false
if (yForce != other.yForce) return false
if (zForce != other.zForce) return false
if (xAxisSupported != other.xAxisSupported) return false
if (yAxisSupported != other.yAxisSupported) return false
if (zAxisSupported != other.zAxisSupported) return false
if (isAvailable != other.isAvailable) return false
if (accuracy != other.accuracy) return false

return true
}

override fun hashCode(): Int {
var result = xForce.hashCode()
result = 31 * result + yForce.hashCode()
result = 31 * result + zForce.hashCode()
result = 31 * result + xAxisSupported.hashCode()
result = 31 * result + yAxisSupported.hashCode()
result = 31 * result + zAxisSupported.hashCode()
result = 31 * result + isAvailable.hashCode()
result = 31 * result + accuracy
return result
}

override fun toString(): String {
return "LimitedAxesAccelerometerSensorState(xForce=$xForce, yForce=$yForce, " +
"zForce=$zForce, xAxisSupported=$xAxisSupported, yAxisSupported=$yAxisSupported, " +
"zAxisSupported=$zAxisSupported, isAvailable=$isAvailable, accuracy=$accuracy)"
}
}

/**
* Creates and [remember]s an instance of [LimitedAxesAccelerometerSensorState].
* @param sensorDelay The rate at which the raw sensor data should be received.
* Defaults to [SensorDelay.Normal].
* @param onError Callback invoked on every error state.
*/
@Composable
fun rememberLimitedAxesAccelerometerSensorState(
sensorDelay: SensorDelay = SensorDelay.Normal,
onError: (throwable: Throwable) -> Unit = {}
): LimitedAxesAccelerometerSensorState {
val sensorState = rememberSensorState(
sensorType = SensorType.AccelerometerLimitedAxes,
sensorDelay = sensorDelay,
onError = onError
)
val accelerometerSensorState = remember { mutableStateOf(LimitedAxesAccelerometerSensorState()) }

LaunchedEffect(
key1 = sensorState,
block = {
val sensorStateValues = sensorState.data
if (sensorStateValues.isNotEmpty()) {
accelerometerSensorState.value = LimitedAxesAccelerometerSensorState(
xForce = sensorStateValues[0],
yForce = sensorStateValues[1],
zForce = sensorStateValues[2],
xAxisSupported = sensorStateValues[3] != 0f,
yAxisSupported = sensorStateValues[4] != 0f,
zAxisSupported = sensorStateValues[5] != 0f,
isAvailable = sensorState.isAvailable,
accuracy = sensorState.accuracy
)
}
}
)

return accelerometerSensorState.value
}
Loading

0 comments on commit 2430cb8

Please sign in to comment.