Home | History | Annotate | Download | only in hardware
      1 /*
      2  * Copyright (C) 2017 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 package android.hardware;
     17 
     18 import android.annotation.IntDef;
     19 import android.os.MemoryFile;
     20 
     21 import dalvik.system.CloseGuard;
     22 
     23 import java.io.IOException;
     24 import java.lang.annotation.Retention;
     25 import java.lang.annotation.RetentionPolicy;
     26 import java.nio.channels.Channel;
     27 import java.util.concurrent.atomic.AtomicBoolean;
     28 
     29 /**
     30  * Class representing a sensor direct channel. Use
     31  * {@link SensorManager#createDirectChannel(android.os.MemoryFile)} or
     32  * {@link SensorManager#createDirectChannel(android.hardware.HardwareBuffer)}
     33  * to obtain an object. The channel object can be then configured
     34  * (see {@link #configure(Sensor, int)})
     35  * to start delivery of sensor events into shared memory buffer.
     36  */
     37 public final class SensorDirectChannel implements Channel {
     38 
     39     // shared memory types
     40 
     41     /** @hide */
     42     @Retention(RetentionPolicy.SOURCE)
     43     @IntDef(flag = true, value = {TYPE_MEMORY_FILE, TYPE_HARDWARE_BUFFER})
     44     public @interface MemoryType {};
     45     /**
     46      * Shared memory type ashmem, wrapped in MemoryFile object.
     47      *
     48      * @see SensorManager#createDirectChannel(MemoryFile)
     49      */
     50     public static final int TYPE_MEMORY_FILE = 1;
     51 
     52     /**
     53      * Shared memory type wrapped by HardwareBuffer object.
     54      *
     55      * @see SensorManager#createDirectChannel(HardwareBuffer)
     56      */
     57     public static final int TYPE_HARDWARE_BUFFER = 2;
     58 
     59     // sensor rate levels
     60 
     61     /** @hide */
     62     @Retention(RetentionPolicy.SOURCE)
     63     @IntDef(flag = true, value = {RATE_STOP, RATE_NORMAL, RATE_FAST, RATE_VERY_FAST})
     64     public @interface RateLevel {};
     65 
     66     /**
     67      * Sensor stopped (no event output).
     68      *
     69      * @see #configure(Sensor, int)
     70      */
     71     public static final int RATE_STOP = 0;
     72     /**
     73      * Sensor operates at nominal rate of 50Hz.
     74      *
     75      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 27.5Hz to
     76      * 110Hz.
     77      *
     78      * @see #configure(Sensor, int)
     79      */
     80     public static final int RATE_NORMAL = 1; //50Hz
     81     /**
     82      * Sensor operates at nominal rate of 200Hz.
     83      *
     84      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 110Hz to
     85      * 440Hz.
     86      *
     87      * @see #configure(Sensor, int)
     88      */
     89     public static final int RATE_FAST = 2; // ~200Hz
     90     /**
     91      * Sensor operates at nominal rate of 800Hz.
     92      *
     93      * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 440Hz to
     94      * 1760Hz.
     95      *
     96      * @see #configure(Sensor, int)
     97      */
     98     public static final int RATE_VERY_FAST = 3; // ~800Hz
     99 
    100     /**
    101      * Determine if a channel is still valid. A channel is invalidated after {@link #close()} is
    102      * called.
    103      *
    104      * @return <code>true</code> if channel is valid.
    105      */
    106     @Override
    107     public boolean isOpen() {
    108         return !mClosed.get();
    109     }
    110 
    111     /** @removed */
    112     @Deprecated
    113     public boolean isValid() {
    114         return isOpen();
    115     }
    116 
    117     /**
    118      * Close sensor direct channel.
    119      *
    120      * Stop all active sensor in the channel and free sensor system resource related to channel.
    121      * Shared memory used for creating the direct channel need to be closed or freed separately.
    122      *
    123      * @see SensorManager#createDirectChannel(MemoryFile)
    124      * @see SensorManager#createDirectChannel(HardwareBuffer)
    125      */
    126     @Override
    127     public void close() {
    128         if (mClosed.compareAndSet(false, true)) {
    129             mCloseGuard.close();
    130             // actual close action
    131             mManager.destroyDirectChannel(this);
    132         }
    133     }
    134 
    135     /**
    136      * Configure sensor rate or stop sensor report.
    137      *
    138      * To start event report of a sensor, or change rate of existing report, call this function with
    139      * rateLevel other than {@link android.hardware.SensorDirectChannel#RATE_STOP}. Sensor events
    140      * will be added into a queue formed by the shared memory used in creation of direction channel.
    141      * Each element of the queue has size of 104 bytes and represents a sensor event. Data
    142      * structure of an element (all fields in little-endian):
    143      *
    144      * <pre>
    145      *   offset   type                    name
    146      * ------------------------------------------------------------------------
    147      *   0x0000   int32_t                 size (always 104)
    148      *   0x0004   int32_t                 sensor report token
    149      *   0x0008   int32_t                 type (see SensorType)
    150      *   0x000C   uint32_t                atomic counter
    151      *   0x0010   int64_t                 timestamp (see Event)
    152      *   0x0018   float[16]/int64_t[8]    data (data type depends on sensor type)
    153      *   0x0058   int32_t[4]              reserved (set to zero)
    154      * </pre>
    155      *
    156      * There are no head or tail pointers. The sequence and frontier of new sensor events is
    157      * determined by the atomic counter, which counts from 1 after creation of direct channel and
    158      * increments 1 for each new event. Atomic counter will wrap back to 1 after it reaches
    159      * UINT32_MAX, skipping value 0 to avoid confusion with uninitialized memory. The writer in
    160      * sensor system will wrap around from the start of shared memory region when it reaches the
    161      * end. If size of memory region is not a multiple of size of element (104 bytes), the residual
    162      * is not used at the end.  Function returns a positive sensor report token on success. This
    163      * token can be used to differentiate sensor events from multiple sensor of the same type. For
    164      * example, if there are two accelerometers in the system A and B, it is guaranteed different
    165      * report tokens will be returned when starting sensor A and B.
    166      *
    167      * To stop a sensor, call this function with rateLevel equal {@link
    168      * android.hardware.SensorDirectChannel#RATE_STOP}. If the sensor parameter is left to be null,
    169      * this will stop all active sensor report associated with the direct channel specified.
    170      * Function return 1 on success or 0 on failure.
    171      *
    172      * @param sensor A {@link android.hardware.Sensor} object to denote sensor to be operated.
    173      * @param rateLevel rate level defined in {@link android.hardware.SensorDirectChannel}.
    174      * @return * starting report or changing rate: positive sensor report token on success,
    175      *                                             0 on failure;
    176      *         * stopping report: 1 on success, 0 on failure.
    177      * @throws NullPointerException when channel is null.
    178      */
    179     public int configure(Sensor sensor, @RateLevel int rateLevel) {
    180         return mManager.configureDirectChannelImpl(this, sensor, rateLevel);
    181     }
    182 
    183     /** @hide */
    184     SensorDirectChannel(SensorManager manager, int id, int type, long size) {
    185         mManager = manager;
    186         mNativeHandle = id;
    187         mType = type;
    188         mSize = size;
    189         mCloseGuard.open("SensorDirectChannel");
    190     }
    191 
    192     /** @hide */
    193     int getNativeHandle() {
    194         return mNativeHandle;
    195     }
    196 
    197     /**
    198      * This function encode handle information in {@link android.os.MemoryFile} into a long array to
    199      * be passed down to native methods.
    200      *
    201      * @hide */
    202     static long[] encodeData(MemoryFile ashmem) {
    203         int fd;
    204         try {
    205             fd = ashmem.getFileDescriptor().getInt$();
    206         } catch (IOException e) {
    207             fd = -1;
    208         }
    209         return new long[] { 1 /*numFds*/, 0 /*numInts*/, fd };
    210     }
    211 
    212     @Override
    213     protected void finalize() throws Throwable {
    214         try {
    215             mCloseGuard.warnIfOpen();
    216             close();
    217         } finally {
    218             super.finalize();
    219         }
    220     }
    221 
    222     private final AtomicBoolean mClosed = new AtomicBoolean();
    223     private final CloseGuard mCloseGuard = CloseGuard.get();
    224     private final SensorManager mManager;
    225     private final int mNativeHandle;
    226     private final long mSize;
    227     private final int mType;
    228 }
    229