blob: 214d3ec28df81d5ae4d313e8ffd066d420be82bb [file] [log] [blame]
Peng Xuccf0c8e2017-01-17 22:16:21 -08001/*
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 */
16package android.hardware;
17
18import android.annotation.IntDef;
19import android.os.MemoryFile;
20
21import dalvik.system.CloseGuard;
22
23import java.io.IOException;
24import java.lang.annotation.Retention;
25import java.lang.annotation.RetentionPolicy;
Peng Xu3c8c6a42017-04-06 18:37:56 -070026import java.nio.channels.Channel;
Peng Xuccf0c8e2017-01-17 22:16:21 -080027import java.util.concurrent.atomic.AtomicBoolean;
28
29/**
Peng Xu3c8c6a42017-04-06 18:37:56 -070030 * 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.
Peng Xuccf0c8e2017-01-17 22:16:21 -080036 */
Peng Xu3c8c6a42017-04-06 18:37:56 -070037public final class SensorDirectChannel implements Channel {
Peng Xuccf0c8e2017-01-17 22:16:21 -080038
39 // shared memory types
40
41 /** @hide */
42 @Retention(RetentionPolicy.SOURCE)
Jeff Sharkeyce8db992017-12-13 20:05:05 -070043 @IntDef(flag = true, prefix = { "TYPE_" }, value = {
44 TYPE_MEMORY_FILE,
45 TYPE_HARDWARE_BUFFER
46 })
47 public @interface MemoryType {}
48
Peng Xuccf0c8e2017-01-17 22:16:21 -080049 /**
50 * Shared memory type ashmem, wrapped in MemoryFile object.
51 *
52 * @see SensorManager#createDirectChannel(MemoryFile)
53 */
Peng Xu3c8c6a42017-04-06 18:37:56 -070054 public static final int TYPE_MEMORY_FILE = 1;
Peng Xuccf0c8e2017-01-17 22:16:21 -080055
56 /**
57 * Shared memory type wrapped by HardwareBuffer object.
58 *
59 * @see SensorManager#createDirectChannel(HardwareBuffer)
60 */
61 public static final int TYPE_HARDWARE_BUFFER = 2;
62
63 // sensor rate levels
64
65 /** @hide */
66 @Retention(RetentionPolicy.SOURCE)
Jeff Sharkeyce8db992017-12-13 20:05:05 -070067 @IntDef(flag = true, prefix = { "RATE_" }, value = {
68 RATE_STOP,
69 RATE_NORMAL,
70 RATE_FAST,
71 RATE_VERY_FAST
72 })
73 public @interface RateLevel {}
Peng Xuccf0c8e2017-01-17 22:16:21 -080074
75 /**
76 * Sensor stopped (no event output).
77 *
Peng Xu3c8c6a42017-04-06 18:37:56 -070078 * @see #configure(Sensor, int)
Peng Xuccf0c8e2017-01-17 22:16:21 -080079 */
80 public static final int RATE_STOP = 0;
81 /**
82 * Sensor operates at nominal rate of 50Hz.
83 *
84 * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 27.5Hz to
85 * 110Hz.
86 *
Peng Xu3c8c6a42017-04-06 18:37:56 -070087 * @see #configure(Sensor, int)
Peng Xuccf0c8e2017-01-17 22:16:21 -080088 */
89 public static final int RATE_NORMAL = 1; //50Hz
90 /**
91 * Sensor operates at nominal rate of 200Hz.
92 *
93 * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 110Hz to
94 * 440Hz.
95 *
Peng Xu3c8c6a42017-04-06 18:37:56 -070096 * @see #configure(Sensor, int)
Peng Xuccf0c8e2017-01-17 22:16:21 -080097 */
98 public static final int RATE_FAST = 2; // ~200Hz
99 /**
100 * Sensor operates at nominal rate of 800Hz.
101 *
102 * The actual rate is expected to be between 55% to 220% of nominal rate, thus between 440Hz to
103 * 1760Hz.
104 *
Peng Xu3c8c6a42017-04-06 18:37:56 -0700105 * @see #configure(Sensor, int)
Peng Xuccf0c8e2017-01-17 22:16:21 -0800106 */
107 public static final int RATE_VERY_FAST = 3; // ~800Hz
108
109 /**
110 * Determine if a channel is still valid. A channel is invalidated after {@link #close()} is
111 * called.
112 *
113 * @return <code>true</code> if channel is valid.
114 */
Peng Xu3c8c6a42017-04-06 18:37:56 -0700115 @Override
116 public boolean isOpen() {
Peng Xufa2672b2016-12-07 03:54:44 -0800117 return !mClosed.get();
Peng Xuccf0c8e2017-01-17 22:16:21 -0800118 }
119
Peng Xu3c8c6a42017-04-06 18:37:56 -0700120 /** @removed */
121 @Deprecated
122 public boolean isValid() {
123 return isOpen();
124 }
125
Peng Xuccf0c8e2017-01-17 22:16:21 -0800126 /**
127 * Close sensor direct channel.
128 *
129 * Stop all active sensor in the channel and free sensor system resource related to channel.
130 * Shared memory used for creating the direct channel need to be closed or freed separately.
131 *
132 * @see SensorManager#createDirectChannel(MemoryFile)
133 * @see SensorManager#createDirectChannel(HardwareBuffer)
134 */
135 @Override
136 public void close() {
Peng Xuccf0c8e2017-01-17 22:16:21 -0800137 if (mClosed.compareAndSet(false, true)) {
Peng Xu3c8c6a42017-04-06 18:37:56 -0700138 mCloseGuard.close();
Peng Xuccf0c8e2017-01-17 22:16:21 -0800139 // actual close action
140 mManager.destroyDirectChannel(this);
141 }
142 }
143
Peng Xu3c8c6a42017-04-06 18:37:56 -0700144 /**
145 * Configure sensor rate or stop sensor report.
146 *
147 * To start event report of a sensor, or change rate of existing report, call this function with
148 * rateLevel other than {@link android.hardware.SensorDirectChannel#RATE_STOP}. Sensor events
149 * will be added into a queue formed by the shared memory used in creation of direction channel.
150 * Each element of the queue has size of 104 bytes and represents a sensor event. Data
151 * structure of an element (all fields in little-endian):
152 *
153 * <pre>
154 * offset type name
155 * ------------------------------------------------------------------------
156 * 0x0000 int32_t size (always 104)
157 * 0x0004 int32_t sensor report token
158 * 0x0008 int32_t type (see SensorType)
159 * 0x000C uint32_t atomic counter
160 * 0x0010 int64_t timestamp (see Event)
161 * 0x0018 float[16]/int64_t[8] data (data type depends on sensor type)
162 * 0x0058 int32_t[4] reserved (set to zero)
163 * </pre>
164 *
165 * There are no head or tail pointers. The sequence and frontier of new sensor events is
166 * determined by the atomic counter, which counts from 1 after creation of direct channel and
167 * increments 1 for each new event. Atomic counter will wrap back to 1 after it reaches
168 * UINT32_MAX, skipping value 0 to avoid confusion with uninitialized memory. The writer in
169 * sensor system will wrap around from the start of shared memory region when it reaches the
170 * end. If size of memory region is not a multiple of size of element (104 bytes), the residual
171 * is not used at the end. Function returns a positive sensor report token on success. This
172 * token can be used to differentiate sensor events from multiple sensor of the same type. For
173 * example, if there are two accelerometers in the system A and B, it is guaranteed different
174 * report tokens will be returned when starting sensor A and B.
175 *
176 * To stop a sensor, call this function with rateLevel equal {@link
177 * android.hardware.SensorDirectChannel#RATE_STOP}. If the sensor parameter is left to be null,
178 * this will stop all active sensor report associated with the direct channel specified.
179 * Function return 1 on success or 0 on failure.
180 *
181 * @param sensor A {@link android.hardware.Sensor} object to denote sensor to be operated.
182 * @param rateLevel rate level defined in {@link android.hardware.SensorDirectChannel}.
183 * @return * starting report or changing rate: positive sensor report token on success,
184 * 0 on failure;
185 * * stopping report: 1 on success, 0 on failure.
186 * @throws NullPointerException when channel is null.
187 */
188 public int configure(Sensor sensor, @RateLevel int rateLevel) {
189 return mManager.configureDirectChannelImpl(this, sensor, rateLevel);
190 }
191
Peng Xuccf0c8e2017-01-17 22:16:21 -0800192 /** @hide */
193 SensorDirectChannel(SensorManager manager, int id, int type, long size) {
194 mManager = manager;
Peng Xufa2672b2016-12-07 03:54:44 -0800195 mNativeHandle = id;
196 mType = type;
197 mSize = size;
Peng Xuccf0c8e2017-01-17 22:16:21 -0800198 mCloseGuard.open("SensorDirectChannel");
199 }
200
Peng Xufa2672b2016-12-07 03:54:44 -0800201 /** @hide */
202 int getNativeHandle() {
203 return mNativeHandle;
204 }
205
206 /**
Peng Xu7d96fa02017-03-04 16:15:45 -0800207 * This function encode handle information in {@link android.os.MemoryFile} into a long array to
208 * be passed down to native methods.
Peng Xufa2672b2016-12-07 03:54:44 -0800209 *
210 * @hide */
211 static long[] encodeData(MemoryFile ashmem) {
212 int fd;
213 try {
214 fd = ashmem.getFileDescriptor().getInt$();
215 } catch (IOException e) {
216 fd = -1;
217 }
218 return new long[] { 1 /*numFds*/, 0 /*numInts*/, fd };
219 }
220
Peng Xuccf0c8e2017-01-17 22:16:21 -0800221 @Override
222 protected void finalize() throws Throwable {
223 try {
Narayan Kamath492e9e82017-03-22 14:28:08 +0000224 if (mCloseGuard != null) {
225 mCloseGuard.warnIfOpen();
226 }
227
Peng Xuccf0c8e2017-01-17 22:16:21 -0800228 close();
229 } finally {
230 super.finalize();
231 }
232 }
233
234 private final AtomicBoolean mClosed = new AtomicBoolean();
235 private final CloseGuard mCloseGuard = CloseGuard.get();
236 private final SensorManager mManager;
Peng Xufa2672b2016-12-07 03:54:44 -0800237 private final int mNativeHandle;
238 private final long mSize;
239 private final int mType;
Peng Xuccf0c8e2017-01-17 22:16:21 -0800240}