github.com/champo/mobile@v0.0.0-20190107162257-dc0771356504/exp/sensor/sensor.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package sensor provides sensor events from various movement sensors.
     6  package sensor // import "golang.org/x/mobile/exp/sensor"
     7  
     8  import (
     9  	"errors"
    10  	"sync"
    11  	"time"
    12  )
    13  
    14  // Type represents a sensor type.
    15  type Type int
    16  
    17  var sensorNames = map[Type]string{
    18  	Accelerometer: "Accelerometer",
    19  	Gyroscope:     "Gyroscope",
    20  	Magnetometer:  "Magnetometer",
    21  }
    22  
    23  // String returns the string representation of the sensor type.
    24  func (t Type) String() string {
    25  	if n, ok := sensorNames[t]; ok {
    26  		return n
    27  	}
    28  	return "Unknown sensor"
    29  }
    30  
    31  const (
    32  	Accelerometer = Type(0)
    33  	Gyroscope     = Type(1)
    34  	Magnetometer  = Type(2)
    35  	nTypes        = Type(3)
    36  )
    37  
    38  // Event represents a sensor event.
    39  type Event struct {
    40  	// Sensor is the type of the sensor the event is coming from.
    41  	Sensor Type
    42  
    43  	// Timestamp is a device specific event time in nanoseconds.
    44  	// Timestamps are not Unix times, they represent a time that is
    45  	// only valid for the device's default sensor.
    46  	Timestamp int64
    47  
    48  	// Data is the event data.
    49  	//
    50  	// If the event source is Accelerometer,
    51  	//  - Data[0]: acceleration force in x axis in m/s^2
    52  	//  - Data[1]: acceleration force in y axis in m/s^2
    53  	//  - Data[2]: acceleration force in z axis in m/s^2
    54  	//
    55  	// If the event source is Gyroscope,
    56  	//  - Data[0]: rate of rotation around the x axis in rad/s
    57  	//  - Data[1]: rate of rotation around the y axis in rad/s
    58  	//  - Data[2]: rate of rotation around the z axis in rad/s
    59  	//
    60  	// If the event source is Magnetometer,
    61  	//  - Data[0]: force of gravity along the x axis in m/s^2
    62  	//  - Data[1]: force of gravity along the y axis in m/s^2
    63  	//  - Data[2]: force of gravity along the z axis in m/s^2
    64  	//
    65  	Data []float64
    66  }
    67  
    68  // TODO(jbd): Move Sender interface definition to a top-level package.
    69  
    70  var (
    71  	// senderMu protects sender.
    72  	senderMu sync.Mutex
    73  
    74  	// sender is notified with the sensor data each time a new event is available.
    75  	sender Sender
    76  )
    77  
    78  // Sender sends an event.
    79  type Sender interface {
    80  	Send(event interface{})
    81  }
    82  
    83  // Notify registers a Sender and sensor events will be sent to s.
    84  // A typical example of Sender implementations is app.App.
    85  // Once you call Notify, you are not allowed to call it again.
    86  // You cannot call Notify with a nil Sender.
    87  func Notify(s Sender) {
    88  	senderMu.Lock()
    89  	defer senderMu.Unlock()
    90  
    91  	if s == nil {
    92  		panic("sensor: cannot set a nil sender")
    93  	}
    94  	if sender != nil {
    95  		panic("sensor: another sender is being notified, cannot set s as the sender")
    96  	}
    97  	sender = s
    98  }
    99  
   100  // Enable enables the specified sensor type with the given delay rate.
   101  // Users must set a non-nil Sender via Notify before enabling a sensor,
   102  // otherwise an error will be returned.
   103  func Enable(t Type, delay time.Duration) error {
   104  	if t < 0 || int(t) >= len(sensorNames) {
   105  		return errors.New("sensor: unknown sensor type")
   106  	}
   107  	if err := validSender(); err != nil {
   108  		return err
   109  	}
   110  	return enable(t, delay)
   111  }
   112  
   113  // Disable disables to feed the manager with the specified sensor.
   114  // Disable is not safe for concurrent use.
   115  func Disable(t Type) error {
   116  	if t < 0 || int(t) >= len(sensorNames) {
   117  		return errors.New("sensor: unknown sensor type")
   118  	}
   119  	return disable(t)
   120  }
   121  
   122  func validSender() error {
   123  	senderMu.Lock()
   124  	defer senderMu.Unlock()
   125  
   126  	if sender == nil {
   127  		return errors.New("sensor: no senders to be notified; cannot enable the sensor")
   128  	}
   129  	return nil
   130  }