1 /* 2 * Copyright (C) 2012 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.hardware; 18 19 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT; 20 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_SENSORS; 21 import static android.content.Context.DEVICE_ID_DEFAULT; 22 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23 24 import android.companion.virtual.VirtualDeviceManager; 25 import android.compat.Compatibility; 26 import android.compat.annotation.ChangeId; 27 import android.compat.annotation.EnabledAfter; 28 import android.compat.annotation.UnsupportedAppUsage; 29 import android.content.BroadcastReceiver; 30 import android.content.Context; 31 import android.content.Intent; 32 import android.content.IntentFilter; 33 import android.content.pm.ApplicationInfo; 34 import android.os.Build; 35 import android.os.Handler; 36 import android.os.Looper; 37 import android.os.MemoryFile; 38 import android.os.MessageQueue; 39 import android.util.Log; 40 import android.util.SparseArray; 41 import android.util.SparseBooleanArray; 42 import android.util.SparseIntArray; 43 44 import com.android.internal.annotations.GuardedBy; 45 46 import dalvik.system.CloseGuard; 47 48 import java.io.IOException; 49 import java.io.UncheckedIOException; 50 import java.lang.ref.WeakReference; 51 import java.util.ArrayList; 52 import java.util.Collections; 53 import java.util.HashMap; 54 import java.util.List; 55 import java.util.Map; 56 import java.util.Optional; 57 58 /** 59 * Sensor manager implementation that communicates with the built-in 60 * system sensors. 61 * 62 * @hide 63 */ 64 public class SystemSensorManager extends SensorManager { 65 //TODO: disable extra logging before release 66 private static final boolean DEBUG_DYNAMIC_SENSOR = true; 67 private static final int MIN_DIRECT_CHANNEL_BUFFER_SIZE = 104; 68 private static final int MAX_LISTENER_COUNT = 128; 69 private static final int CAPPED_SAMPLING_PERIOD_US = 5000; 70 private static final int CAPPED_SAMPLING_RATE_LEVEL = SensorDirectChannel.RATE_NORMAL; 71 72 private static final String HIGH_SAMPLING_RATE_SENSORS_PERMISSION = 73 "android.permission.HIGH_SAMPLING_RATE_SENSORS"; 74 /** 75 * For apps targeting S and above, a SecurityException is thrown when they do not have 76 * HIGH_SAMPLING_RATE_SENSORS permission, run in debug mode, and request sampling rates that 77 * are faster than 200 Hz. 78 */ 79 @ChangeId 80 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 81 static final long CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION = 136069189L; 82 nativeClassInit()83 private static native void nativeClassInit(); nativeCreate(String opPackageName)84 private static native long nativeCreate(String opPackageName); nativeGetSensorAtIndex(long nativeInstance, Sensor sensor, int index)85 private static native boolean nativeGetSensorAtIndex(long nativeInstance, 86 Sensor sensor, int index); nativeGetDefaultDeviceSensorAtIndex(long nativeInstance, Sensor sensor, int index)87 private static native boolean nativeGetDefaultDeviceSensorAtIndex(long nativeInstance, 88 Sensor sensor, int index); nativeGetDynamicSensors(long nativeInstance, List<Sensor> list)89 private static native void nativeGetDynamicSensors(long nativeInstance, List<Sensor> list); nativeGetRuntimeSensors( long nativeInstance, int deviceId, List<Sensor> list)90 private static native void nativeGetRuntimeSensors( 91 long nativeInstance, int deviceId, List<Sensor> list); nativeIsDataInjectionEnabled(long nativeInstance)92 private static native boolean nativeIsDataInjectionEnabled(long nativeInstance); nativeIsReplayDataInjectionEnabled(long nativeInstance)93 private static native boolean nativeIsReplayDataInjectionEnabled(long nativeInstance); nativeIsHalBypassReplayDataInjectionEnabled(long nativeInstance)94 private static native boolean nativeIsHalBypassReplayDataInjectionEnabled(long nativeInstance); 95 nativeCreateDirectChannel( long nativeInstance, int deviceId, long size, int channelType, int fd, HardwareBuffer buffer)96 private static native int nativeCreateDirectChannel( 97 long nativeInstance, int deviceId, long size, int channelType, int fd, 98 HardwareBuffer buffer); nativeDestroyDirectChannel( long nativeInstance, int channelHandle)99 private static native void nativeDestroyDirectChannel( 100 long nativeInstance, int channelHandle); nativeConfigDirectChannel( long nativeInstance, int channelHandle, int sensorHandle, int rate)101 private static native int nativeConfigDirectChannel( 102 long nativeInstance, int channelHandle, int sensorHandle, int rate); 103 nativeSetOperationParameter( long nativeInstance, int handle, int type, float[] floatValues, int[] intValues)104 private static native int nativeSetOperationParameter( 105 long nativeInstance, int handle, int type, float[] floatValues, int[] intValues); 106 107 private static final Object sLock = new Object(); 108 @GuardedBy("sLock") 109 private static boolean sNativeClassInited = false; 110 @GuardedBy("sLock") 111 private static InjectEventQueue sInjectEventQueue = null; 112 113 private final ArrayList<Sensor> mFullSensorsList = new ArrayList<>(); 114 private List<Sensor> mFullDynamicSensorsList = new ArrayList<>(); 115 private final SparseArray<List<Sensor>> mFullRuntimeSensorListByDevice = new SparseArray<>(); 116 private final SparseArray<SparseArray<List<Sensor>>> mRuntimeSensorListByDeviceByType = 117 new SparseArray<>(); 118 119 private boolean mDynamicSensorListDirty = true; 120 121 private final HashMap<Integer, Sensor> mHandleToSensor = new HashMap<>(); 122 123 // Listener list 124 private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners = 125 new HashMap<SensorEventListener, SensorEventQueue>(); 126 private final HashMap<TriggerEventListener, TriggerEventQueue> mTriggerListeners = 127 new HashMap<TriggerEventListener, TriggerEventQueue>(); 128 129 // Dynamic Sensor callbacks 130 private HashMap<DynamicSensorCallback, Handler> 131 mDynamicSensorCallbacks = new HashMap<>(); 132 private BroadcastReceiver mDynamicSensorBroadcastReceiver; 133 private BroadcastReceiver mRuntimeSensorBroadcastReceiver; 134 private VirtualDeviceManager.VirtualDeviceListener mVirtualDeviceListener; 135 136 // Looper associated with the context in which this instance was created. 137 private final Looper mMainLooper; 138 private final int mTargetSdkLevel; 139 private final boolean mIsPackageDebuggable; 140 private final Context mContext; 141 private final long mNativeInstance; 142 private VirtualDeviceManager mVdm; 143 144 private Optional<Boolean> mHasHighSamplingRateSensorsPermission = Optional.empty(); 145 146 /** {@hide} */ SystemSensorManager(Context context, Looper mainLooper)147 public SystemSensorManager(Context context, Looper mainLooper) { 148 synchronized (sLock) { 149 if (!sNativeClassInited) { 150 sNativeClassInited = true; 151 nativeClassInit(); 152 } 153 } 154 155 mMainLooper = mainLooper; 156 ApplicationInfo appInfo = context.getApplicationInfo(); 157 mTargetSdkLevel = appInfo.targetSdkVersion; 158 mContext = context; 159 mNativeInstance = nativeCreate(context.getOpPackageName()); 160 mIsPackageDebuggable = (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE)); 161 162 // initialize the sensor list 163 for (int index = 0;; ++index) { 164 Sensor sensor = new Sensor(); 165 if (!nativeGetDefaultDeviceSensorAtIndex(mNativeInstance, sensor, index)) break; 166 mFullSensorsList.add(sensor); 167 mHandleToSensor.put(sensor.getHandle(), sensor); 168 } 169 } 170 171 /** @hide */ 172 @Override getSensorList(int type)173 public List<Sensor> getSensorList(int type) { 174 final int deviceId = mContext.getDeviceId(); 175 if (isDeviceSensorPolicyDefault(deviceId)) { 176 return super.getSensorList(type); 177 } 178 179 // Cache the per-device lists on demand. 180 List<Sensor> list; 181 synchronized (mFullRuntimeSensorListByDevice) { 182 List<Sensor> fullList = mFullRuntimeSensorListByDevice.get(deviceId); 183 if (fullList == null) { 184 fullList = createRuntimeSensorListLocked(deviceId); 185 } 186 SparseArray<List<Sensor>> deviceSensorListByType = 187 mRuntimeSensorListByDeviceByType.get(deviceId); 188 list = deviceSensorListByType.get(type); 189 if (list == null) { 190 if (type == Sensor.TYPE_ALL) { 191 list = fullList; 192 } else { 193 list = new ArrayList<>(); 194 for (Sensor i : fullList) { 195 if (i.getType() == type) { 196 list.add(i); 197 } 198 } 199 } 200 list = Collections.unmodifiableList(list); 201 deviceSensorListByType.append(type, list); 202 } 203 } 204 return list; 205 } 206 207 /** @hide */ 208 @Override getFullSensorList()209 protected List<Sensor> getFullSensorList() { 210 final int deviceId = mContext.getDeviceId(); 211 if (isDeviceSensorPolicyDefault(deviceId)) { 212 return mFullSensorsList; 213 } 214 215 List<Sensor> fullList; 216 synchronized (mFullRuntimeSensorListByDevice) { 217 fullList = mFullRuntimeSensorListByDevice.get(deviceId); 218 if (fullList == null) { 219 fullList = createRuntimeSensorListLocked(deviceId); 220 } 221 } 222 return fullList; 223 } 224 225 /** @hide */ 226 @Override getSensorByHandle(int sensorHandle)227 public Sensor getSensorByHandle(int sensorHandle) { 228 return mHandleToSensor.get(sensorHandle); 229 } 230 231 /** @hide */ 232 @Override getFullDynamicSensorList()233 protected List<Sensor> getFullDynamicSensorList() { 234 // only set up broadcast receiver if the application tries to find dynamic sensors or 235 // explicitly register a DynamicSensorCallback 236 setupDynamicSensorBroadcastReceiver(); 237 updateDynamicSensorList(); 238 return mFullDynamicSensorsList; 239 } 240 241 /** @hide */ 242 @Override registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags)243 protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, 244 int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) { 245 if (listener == null || sensor == null) { 246 Log.e(TAG, "sensor or listener is null"); 247 return false; 248 } 249 // Trigger Sensors should use the requestTriggerSensor call. 250 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 251 Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor."); 252 return false; 253 } 254 if (maxBatchReportLatencyUs < 0 || delayUs < 0) { 255 Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative"); 256 return false; 257 } 258 if (mSensorListeners.size() >= MAX_LISTENER_COUNT) { 259 throw new IllegalStateException("register failed, " 260 + "the sensor listeners size has exceeded the maximum limit " 261 + MAX_LISTENER_COUNT); 262 } 263 264 // Invariants to preserve: 265 // - one Looper per SensorEventListener 266 // - one Looper per SensorEventQueue 267 // We map SensorEventListener to a SensorEventQueue, which holds the looper 268 synchronized (mSensorListeners) { 269 SensorEventQueue queue = mSensorListeners.get(listener); 270 if (queue == null) { 271 Looper looper = (handler != null) ? handler.getLooper() : mMainLooper; 272 final String fullClassName = 273 listener.getClass().getEnclosingClass() != null 274 ? listener.getClass().getEnclosingClass().getName() 275 : listener.getClass().getName(); 276 queue = new SensorEventQueue(listener, looper, this, fullClassName); 277 if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) { 278 queue.dispose(); 279 return false; 280 } 281 mSensorListeners.put(listener, queue); 282 return true; 283 } else { 284 return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs); 285 } 286 } 287 } 288 289 /** @hide */ 290 @Override unregisterListenerImpl(SensorEventListener listener, Sensor sensor)291 protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) { 292 // Trigger Sensors should use the cancelTriggerSensor call. 293 if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 294 return; 295 } 296 297 synchronized (mSensorListeners) { 298 SensorEventQueue queue = mSensorListeners.get(listener); 299 if (queue != null) { 300 boolean result; 301 if (sensor == null) { 302 result = queue.removeAllSensors(); 303 } else { 304 result = queue.removeSensor(sensor, true); 305 } 306 if (result && !queue.hasSensors()) { 307 mSensorListeners.remove(listener); 308 queue.dispose(); 309 } 310 } 311 } 312 } 313 314 /** @hide */ 315 @Override requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor)316 protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) { 317 if (sensor == null) throw new IllegalArgumentException("sensor cannot be null"); 318 319 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 320 321 if (sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) return false; 322 323 if (mTriggerListeners.size() >= MAX_LISTENER_COUNT) { 324 throw new IllegalStateException("request failed, " 325 + "the trigger listeners size has exceeded the maximum limit " 326 + MAX_LISTENER_COUNT); 327 } 328 329 synchronized (mTriggerListeners) { 330 TriggerEventQueue queue = mTriggerListeners.get(listener); 331 if (queue == null) { 332 final String fullClassName = 333 listener.getClass().getEnclosingClass() != null 334 ? listener.getClass().getEnclosingClass().getName() 335 : listener.getClass().getName(); 336 queue = new TriggerEventQueue(listener, mMainLooper, this, fullClassName); 337 if (!queue.addSensor(sensor, 0, 0)) { 338 queue.dispose(); 339 return false; 340 } 341 mTriggerListeners.put(listener, queue); 342 return true; 343 } else { 344 return queue.addSensor(sensor, 0, 0); 345 } 346 } 347 } 348 349 /** @hide */ 350 @Override cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, boolean disable)351 protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor, 352 boolean disable) { 353 if (sensor != null && sensor.getReportingMode() != Sensor.REPORTING_MODE_ONE_SHOT) { 354 return false; 355 } 356 synchronized (mTriggerListeners) { 357 TriggerEventQueue queue = mTriggerListeners.get(listener); 358 if (queue != null) { 359 boolean result; 360 if (sensor == null) { 361 result = queue.removeAllSensors(); 362 } else { 363 result = queue.removeSensor(sensor, disable); 364 } 365 if (result && !queue.hasSensors()) { 366 mTriggerListeners.remove(listener); 367 queue.dispose(); 368 } 369 return result; 370 } 371 return false; 372 } 373 } 374 flushImpl(SensorEventListener listener)375 protected boolean flushImpl(SensorEventListener listener) { 376 if (listener == null) throw new IllegalArgumentException("listener cannot be null"); 377 378 synchronized (mSensorListeners) { 379 SensorEventQueue queue = mSensorListeners.get(listener); 380 if (queue == null) { 381 return false; 382 } else { 383 return (queue.flush() == 0); 384 } 385 } 386 } 387 initDataInjectionImpl(boolean enable, @DataInjectionMode int mode)388 protected boolean initDataInjectionImpl(boolean enable, @DataInjectionMode int mode) { 389 synchronized (sLock) { 390 boolean isDataInjectionModeEnabled = false; 391 if (enable) { 392 switch (mode) { 393 case DATA_INJECTION: 394 isDataInjectionModeEnabled = nativeIsDataInjectionEnabled(mNativeInstance); 395 break; 396 case REPLAY_DATA_INJECTION: 397 isDataInjectionModeEnabled = nativeIsReplayDataInjectionEnabled( 398 mNativeInstance); 399 break; 400 case HAL_BYPASS_REPLAY_DATA_INJECTION: 401 isDataInjectionModeEnabled = nativeIsHalBypassReplayDataInjectionEnabled( 402 mNativeInstance); 403 break; 404 default: 405 break; 406 } 407 // The HAL does not support injection OR SensorService hasn't been set in DI mode. 408 if (!isDataInjectionModeEnabled) { 409 Log.e(TAG, "The correct Data Injection mode has not been enabled"); 410 return false; 411 } 412 if (sInjectEventQueue != null && sInjectEventQueue.getDataInjectionMode() != mode) { 413 // The inject event queue has been initialized for a different type of DI 414 // close it and create a new one 415 sInjectEventQueue.dispose(); 416 sInjectEventQueue = null; 417 } 418 // Initialize a client for data_injection. 419 if (sInjectEventQueue == null) { 420 try { 421 sInjectEventQueue = new InjectEventQueue( 422 mMainLooper, this, mode, mContext.getPackageName()); 423 } catch (RuntimeException e) { 424 Log.e(TAG, "Cannot create InjectEventQueue: " + e); 425 } 426 } 427 return sInjectEventQueue != null; 428 } else { 429 // If data injection is being disabled clean up the native resources. 430 if (sInjectEventQueue != null) { 431 sInjectEventQueue.dispose(); 432 sInjectEventQueue = null; 433 } 434 return true; 435 } 436 } 437 } 438 injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, long timestamp)439 protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy, 440 long timestamp) { 441 synchronized (sLock) { 442 if (sInjectEventQueue == null) { 443 Log.e(TAG, "Data injection mode not activated before calling injectSensorData"); 444 return false; 445 } 446 if (sInjectEventQueue.getDataInjectionMode() != HAL_BYPASS_REPLAY_DATA_INJECTION 447 && !sensor.isDataInjectionSupported()) { 448 // DI mode and Replay DI mode require support from the sensor HAL 449 // HAL Bypass mode doesn't require this. 450 throw new IllegalArgumentException("sensor does not support data injection"); 451 } 452 int ret = sInjectEventQueue.injectSensorData(sensor.getHandle(), values, accuracy, 453 timestamp); 454 // If there are any errors in data injection clean up the native resources. 455 if (ret != 0) { 456 sInjectEventQueue.dispose(); 457 sInjectEventQueue = null; 458 } 459 return ret == 0; 460 } 461 } 462 cleanupSensorConnection(Sensor sensor)463 private void cleanupSensorConnection(Sensor sensor) { 464 mHandleToSensor.remove(sensor.getHandle()); 465 466 if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) { 467 synchronized (mTriggerListeners) { 468 HashMap<TriggerEventListener, TriggerEventQueue> triggerListeners = 469 new HashMap<TriggerEventListener, TriggerEventQueue>(mTriggerListeners); 470 471 for (TriggerEventListener l : triggerListeners.keySet()) { 472 if (DEBUG_DYNAMIC_SENSOR) { 473 Log.i(TAG, "removed trigger listener" + l.toString() 474 + " due to sensor disconnection"); 475 } 476 cancelTriggerSensorImpl(l, sensor, true); 477 } 478 } 479 } else { 480 synchronized (mSensorListeners) { 481 HashMap<SensorEventListener, SensorEventQueue> sensorListeners = 482 new HashMap<SensorEventListener, SensorEventQueue>(mSensorListeners); 483 484 for (SensorEventListener l: sensorListeners.keySet()) { 485 if (DEBUG_DYNAMIC_SENSOR) { 486 Log.i(TAG, "removed event listener" + l.toString() 487 + " due to sensor disconnection"); 488 } 489 unregisterListenerImpl(l, sensor); 490 } 491 } 492 } 493 } 494 updateDynamicSensorList()495 private void updateDynamicSensorList() { 496 synchronized (mFullDynamicSensorsList) { 497 if (mDynamicSensorListDirty) { 498 List<Sensor> list = new ArrayList<>(); 499 nativeGetDynamicSensors(mNativeInstance, list); 500 501 final List<Sensor> updatedList = new ArrayList<>(); 502 final List<Sensor> addedList = new ArrayList<>(); 503 final List<Sensor> removedList = new ArrayList<>(); 504 505 boolean changed = diffSortedSensorList( 506 mFullDynamicSensorsList, list, updatedList, addedList, removedList); 507 508 if (changed) { 509 if (DEBUG_DYNAMIC_SENSOR) { 510 Log.i(TAG, "DYNS dynamic sensor list cached should be updated"); 511 } 512 mFullDynamicSensorsList = updatedList; 513 514 for (Sensor s: addedList) { 515 mHandleToSensor.put(s.getHandle(), s); 516 } 517 518 Handler mainHandler = new Handler(mContext.getMainLooper()); 519 520 synchronized (mDynamicSensorCallbacks) { 521 for (Map.Entry<DynamicSensorCallback, Handler> entry : 522 mDynamicSensorCallbacks.entrySet()) { 523 final DynamicSensorCallback callback = entry.getKey(); 524 Handler handler = 525 entry.getValue() == null ? mainHandler : entry.getValue(); 526 527 handler.post(new Runnable() { 528 @Override 529 public void run() { 530 for (Sensor s: addedList) { 531 callback.onDynamicSensorConnected(s); 532 } 533 for (Sensor s: removedList) { 534 callback.onDynamicSensorDisconnected(s); 535 } 536 } 537 }); 538 } 539 } 540 541 for (Sensor s: removedList) { 542 cleanupSensorConnection(s); 543 } 544 } 545 546 mDynamicSensorListDirty = false; 547 } 548 } 549 } 550 createRuntimeSensorListLocked(int deviceId)551 private List<Sensor> createRuntimeSensorListLocked(int deviceId) { 552 setupVirtualDeviceListener(); 553 List<Sensor> list = new ArrayList<>(); 554 nativeGetRuntimeSensors(mNativeInstance, deviceId, list); 555 mFullRuntimeSensorListByDevice.put(deviceId, list); 556 mRuntimeSensorListByDeviceByType.put(deviceId, new SparseArray<>()); 557 for (Sensor s : list) { 558 mHandleToSensor.put(s.getHandle(), s); 559 } 560 return list; 561 } 562 setupVirtualDeviceListener()563 private void setupVirtualDeviceListener() { 564 if (mVirtualDeviceListener != null) { 565 return; 566 } 567 if (mVdm == null) { 568 mVdm = mContext.getSystemService(VirtualDeviceManager.class); 569 if (mVdm == null) { 570 return; 571 } 572 } 573 mVirtualDeviceListener = new VirtualDeviceManager.VirtualDeviceListener() { 574 @Override 575 public void onVirtualDeviceClosed(int deviceId) { 576 synchronized (mFullRuntimeSensorListByDevice) { 577 List<Sensor> removedSensors = 578 mFullRuntimeSensorListByDevice.removeReturnOld(deviceId); 579 if (removedSensors != null) { 580 for (Sensor s : removedSensors) { 581 cleanupSensorConnection(s); 582 } 583 } 584 mRuntimeSensorListByDeviceByType.remove(deviceId); 585 } 586 } 587 }; 588 mVdm.registerVirtualDeviceListener(mContext.getMainExecutor(), mVirtualDeviceListener); 589 } 590 setupDynamicSensorBroadcastReceiver()591 private void setupDynamicSensorBroadcastReceiver() { 592 if (mDynamicSensorBroadcastReceiver == null) { 593 mDynamicSensorBroadcastReceiver = new BroadcastReceiver() { 594 @Override 595 public void onReceive(Context context, Intent intent) { 596 if (intent.getAction().equals(Intent.ACTION_DYNAMIC_SENSOR_CHANGED)) { 597 if (DEBUG_DYNAMIC_SENSOR) { 598 Log.i(TAG, "DYNS received DYNAMIC_SENSOR_CHANGED broadcast"); 599 } 600 // Dynamic sensors probably changed 601 mDynamicSensorListDirty = true; 602 updateDynamicSensorList(); 603 } 604 } 605 }; 606 607 IntentFilter filter = new IntentFilter("dynamic_sensor_change"); 608 filter.addAction(Intent.ACTION_DYNAMIC_SENSOR_CHANGED); 609 mContext.registerReceiver(mDynamicSensorBroadcastReceiver, filter, 610 Context.RECEIVER_NOT_EXPORTED); 611 } 612 } 613 614 /** @hide */ registerDynamicSensorCallbackImpl( DynamicSensorCallback callback, Handler handler)615 protected void registerDynamicSensorCallbackImpl( 616 DynamicSensorCallback callback, Handler handler) { 617 if (DEBUG_DYNAMIC_SENSOR) { 618 Log.i(TAG, "DYNS Register dynamic sensor callback"); 619 } 620 621 if (callback == null) { 622 throw new IllegalArgumentException("callback cannot be null"); 623 } 624 synchronized (mDynamicSensorCallbacks) { 625 if (mDynamicSensorCallbacks.containsKey(callback)) { 626 // has been already registered, ignore 627 return; 628 } 629 630 setupDynamicSensorBroadcastReceiver(); 631 mDynamicSensorCallbacks.put(callback, handler); 632 } 633 } 634 635 /** @hide */ unregisterDynamicSensorCallbackImpl( DynamicSensorCallback callback)636 protected void unregisterDynamicSensorCallbackImpl( 637 DynamicSensorCallback callback) { 638 if (DEBUG_DYNAMIC_SENSOR) { 639 Log.i(TAG, "Removing dynamic sensor listener"); 640 } 641 synchronized (mDynamicSensorCallbacks) { 642 mDynamicSensorCallbacks.remove(callback); 643 } 644 } 645 646 /* 647 * Find the difference of two List<Sensor> assuming List are sorted by handle of sensor, 648 * assuming the input list is already sorted by handle. Inputs are ol and nl; outputs are 649 * updated, added and removed. Any of the output lists can be null in case the result is not 650 * interested. 651 */ diffSortedSensorList( List<Sensor> oldList, List<Sensor> newList, List<Sensor> updated, List<Sensor> added, List<Sensor> removed)652 private static boolean diffSortedSensorList( 653 List<Sensor> oldList, List<Sensor> newList, List<Sensor> updated, 654 List<Sensor> added, List<Sensor> removed) { 655 656 boolean changed = false; 657 658 int i = 0, j = 0; 659 while (true) { 660 if (j < oldList.size() && (i >= newList.size() 661 || newList.get(i).getHandle() > oldList.get(j).getHandle())) { 662 changed = true; 663 if (removed != null) { 664 removed.add(oldList.get(j)); 665 } 666 ++j; 667 } else if (i < newList.size() && (j >= oldList.size() 668 || newList.get(i).getHandle() < oldList.get(j).getHandle())) { 669 changed = true; 670 if (added != null) { 671 added.add(newList.get(i)); 672 } 673 if (updated != null) { 674 updated.add(newList.get(i)); 675 } 676 ++i; 677 } else if (i < newList.size() && j < oldList.size() 678 && newList.get(i).getHandle() == oldList.get(j).getHandle()) { 679 if (updated != null) { 680 updated.add(oldList.get(j)); 681 } 682 ++i; 683 ++j; 684 } else { 685 break; 686 } 687 } 688 return changed; 689 } 690 691 /** @hide */ configureDirectChannelImpl( SensorDirectChannel channel, Sensor sensor, int rate)692 protected int configureDirectChannelImpl( 693 SensorDirectChannel channel, Sensor sensor, int rate) { 694 if (!channel.isOpen()) { 695 throw new IllegalStateException("channel is closed"); 696 } 697 698 if (rate < SensorDirectChannel.RATE_STOP 699 || rate > SensorDirectChannel.RATE_VERY_FAST) { 700 throw new IllegalArgumentException("rate parameter invalid"); 701 } 702 703 if (sensor == null && rate != SensorDirectChannel.RATE_STOP) { 704 // the stop all sensors case 705 throw new IllegalArgumentException( 706 "when sensor is null, rate can only be DIRECT_RATE_STOP"); 707 } 708 709 int sensorHandle = (sensor == null) ? -1 : sensor.getHandle(); 710 if (sensor != null 711 && isSensorInCappedSet(sensor.getType()) 712 && rate > CAPPED_SAMPLING_RATE_LEVEL 713 && mIsPackageDebuggable 714 && !hasHighSamplingRateSensorsPermission() 715 && Compatibility.isChangeEnabled(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION)) { 716 throw new SecurityException("To use the sampling rate level " + rate 717 + ", app needs to declare the normal permission" 718 + " HIGH_SAMPLING_RATE_SENSORS."); 719 } 720 721 int ret = nativeConfigDirectChannel( 722 mNativeInstance, channel.getNativeHandle(), sensorHandle, rate); 723 if (rate == SensorDirectChannel.RATE_STOP) { 724 return (ret == 0) ? 1 : 0; 725 } else { 726 return (ret > 0) ? ret : 0; 727 } 728 } 729 730 /** @hide */ createDirectChannelImpl( MemoryFile memoryFile, HardwareBuffer hardwareBuffer)731 protected SensorDirectChannel createDirectChannelImpl( 732 MemoryFile memoryFile, HardwareBuffer hardwareBuffer) { 733 int deviceId = mContext.getDeviceId(); 734 if (isDeviceSensorPolicyDefault(deviceId)) { 735 deviceId = DEVICE_ID_DEFAULT; 736 } 737 int id; 738 int type; 739 long size; 740 if (memoryFile != null) { 741 int fd; 742 try { 743 fd = memoryFile.getFileDescriptor().getInt$(); 744 } catch (IOException e) { 745 throw new IllegalArgumentException("MemoryFile object is not valid"); 746 } 747 748 if (memoryFile.length() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) { 749 throw new IllegalArgumentException( 750 "Size of MemoryFile has to be greater than " 751 + MIN_DIRECT_CHANNEL_BUFFER_SIZE); 752 } 753 754 size = memoryFile.length(); 755 id = nativeCreateDirectChannel(mNativeInstance, deviceId, size, 756 SensorDirectChannel.TYPE_MEMORY_FILE, fd, null); 757 if (id <= 0) { 758 throw new UncheckedIOException( 759 new IOException("create MemoryFile direct channel failed " + id)); 760 } 761 type = SensorDirectChannel.TYPE_MEMORY_FILE; 762 } else if (hardwareBuffer != null) { 763 if (hardwareBuffer.getFormat() != HardwareBuffer.BLOB) { 764 throw new IllegalArgumentException("Format of HardwareBuffer must be BLOB"); 765 } 766 if (hardwareBuffer.getHeight() != 1) { 767 throw new IllegalArgumentException("Height of HardwareBuffer must be 1"); 768 } 769 if (hardwareBuffer.getWidth() < MIN_DIRECT_CHANNEL_BUFFER_SIZE) { 770 throw new IllegalArgumentException( 771 "Width if HardwareBuffer must be greater than " 772 + MIN_DIRECT_CHANNEL_BUFFER_SIZE); 773 } 774 if ((hardwareBuffer.getUsage() & HardwareBuffer.USAGE_SENSOR_DIRECT_DATA) == 0) { 775 throw new IllegalArgumentException( 776 "HardwareBuffer must set usage flag USAGE_SENSOR_DIRECT_DATA"); 777 } 778 size = hardwareBuffer.getWidth(); 779 id = nativeCreateDirectChannel( 780 mNativeInstance, deviceId, size, SensorDirectChannel.TYPE_HARDWARE_BUFFER, 781 -1, hardwareBuffer); 782 if (id <= 0) { 783 throw new UncheckedIOException( 784 new IOException("create HardwareBuffer direct channel failed " + id)); 785 } 786 type = SensorDirectChannel.TYPE_HARDWARE_BUFFER; 787 } else { 788 throw new NullPointerException("shared memory object cannot be null"); 789 } 790 return new SensorDirectChannel(this, id, type, size); 791 } 792 793 /** @hide */ destroyDirectChannelImpl(SensorDirectChannel channel)794 protected void destroyDirectChannelImpl(SensorDirectChannel channel) { 795 if (channel != null) { 796 nativeDestroyDirectChannel(mNativeInstance, channel.getNativeHandle()); 797 } 798 } 799 800 /* 801 * BaseEventQueue is the communication channel with the sensor service, 802 * SensorEventQueue, TriggerEventQueue are subclasses and there is one-to-one mapping between 803 * the queues and the listeners. InjectEventQueue is also a sub-class which is a special case 804 * where data is being injected into the sensor HAL through the sensor service. It is not 805 * associated with any listener and there is one InjectEventQueue associated with a 806 * SensorManager instance. 807 */ 808 private abstract static class BaseEventQueue { nativeInitBaseEventQueue(long nativeManager, WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, String packageName, int mode, String opPackageName, String attributionTag)809 private static native long nativeInitBaseEventQueue(long nativeManager, 810 WeakReference<BaseEventQueue> eventQWeak, MessageQueue msgQ, 811 String packageName, int mode, String opPackageName, String attributionTag); nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs)812 private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, 813 int maxBatchReportLatencyUs); nativeDisableSensor(long eventQ, int handle)814 private static native int nativeDisableSensor(long eventQ, int handle); nativeDestroySensorEventQueue(long eventQ)815 private static native void nativeDestroySensorEventQueue(long eventQ); nativeFlushSensor(long eventQ)816 private static native int nativeFlushSensor(long eventQ); nativeInjectSensorData(long eventQ, int handle, float[] values, int accuracy, long timestamp)817 private static native int nativeInjectSensorData(long eventQ, int handle, 818 float[] values, int accuracy, long timestamp); 819 820 private long mNativeSensorEventQueue; 821 private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); 822 protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); 823 protected final SparseIntArray mSensorDiscontinuityCounts = new SparseIntArray(); 824 private final CloseGuard mCloseGuard = CloseGuard.get(); 825 protected final SystemSensorManager mManager; 826 827 protected static final int OPERATING_MODE_NORMAL = 0; 828 protected static final int OPERATING_MODE_DATA_INJECTION = 1; 829 protected static final int OPERATING_MODE_REPLAY_DATA_INJECTION = 3; 830 protected static final int OPERATING_MODE_HAL_BYPASS_REPLAY_DATA_INJECTION = 4; 831 BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName)832 BaseEventQueue(Looper looper, SystemSensorManager manager, int mode, String packageName) { 833 if (packageName == null) packageName = ""; 834 mNativeSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance, 835 new WeakReference<>(this), looper.getQueue(), 836 packageName, mode, manager.mContext.getOpPackageName(), 837 manager.mContext.getAttributionTag()); 838 mCloseGuard.open("BaseEventQueue.dispose"); 839 mManager = manager; 840 } 841 dispose()842 public void dispose() { 843 dispose(false); 844 } 845 addSensor( Sensor sensor, int delayUs, int maxBatchReportLatencyUs)846 public boolean addSensor( 847 Sensor sensor, int delayUs, int maxBatchReportLatencyUs) { 848 // Check if already present. 849 int handle = sensor.getHandle(); 850 if (mActiveSensors.get(handle)) return false; 851 852 // Get ready to receive events before calling enable. 853 mActiveSensors.put(handle, true); 854 addSensorEvent(sensor); 855 if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) { 856 // Try continuous mode if batching fails. 857 if (maxBatchReportLatencyUs == 0 858 || maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) { 859 removeSensor(sensor, false); 860 return false; 861 } 862 } 863 return true; 864 } 865 removeAllSensors()866 public boolean removeAllSensors() { 867 for (int i = 0; i < mActiveSensors.size(); i++) { 868 if (mActiveSensors.valueAt(i) == true) { 869 int handle = mActiveSensors.keyAt(i); 870 Sensor sensor = mManager.mHandleToSensor.get(handle); 871 if (sensor != null) { 872 disableSensor(sensor); 873 mActiveSensors.put(handle, false); 874 removeSensorEvent(sensor); 875 } else { 876 // sensor just disconnected -- just ignore. 877 } 878 } 879 } 880 return true; 881 } 882 removeSensor(Sensor sensor, boolean disable)883 public boolean removeSensor(Sensor sensor, boolean disable) { 884 final int handle = sensor.getHandle(); 885 if (mActiveSensors.get(handle)) { 886 if (disable) disableSensor(sensor); 887 mActiveSensors.put(sensor.getHandle(), false); 888 removeSensorEvent(sensor); 889 return true; 890 } 891 return false; 892 } 893 flush()894 public int flush() { 895 if (mNativeSensorEventQueue == 0) throw new NullPointerException(); 896 return nativeFlushSensor(mNativeSensorEventQueue); 897 } 898 hasSensors()899 public boolean hasSensors() { 900 // no more sensors are set 901 return mActiveSensors.indexOfValue(true) >= 0; 902 } 903 904 @Override finalize()905 protected void finalize() throws Throwable { 906 try { 907 dispose(true); 908 } finally { 909 super.finalize(); 910 } 911 } 912 dispose(boolean finalized)913 private void dispose(boolean finalized) { 914 if (mCloseGuard != null) { 915 if (finalized) { 916 mCloseGuard.warnIfOpen(); 917 } 918 mCloseGuard.close(); 919 } 920 if (mNativeSensorEventQueue != 0) { 921 nativeDestroySensorEventQueue(mNativeSensorEventQueue); 922 mNativeSensorEventQueue = 0; 923 } 924 } 925 enableSensor( Sensor sensor, int rateUs, int maxBatchReportLatencyUs)926 private int enableSensor( 927 Sensor sensor, int rateUs, int maxBatchReportLatencyUs) { 928 if (mNativeSensorEventQueue == 0) throw new NullPointerException(); 929 if (sensor == null) throw new NullPointerException(); 930 if (mManager.isSensorInCappedSet(sensor.getType()) 931 && rateUs < CAPPED_SAMPLING_PERIOD_US 932 && mManager.mIsPackageDebuggable 933 && !mManager.hasHighSamplingRateSensorsPermission() 934 && Compatibility.isChangeEnabled(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION)) { 935 throw new SecurityException("To use the sampling rate of " + rateUs 936 + " microseconds, app needs to declare the normal permission" 937 + " HIGH_SAMPLING_RATE_SENSORS."); 938 } 939 return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs, 940 maxBatchReportLatencyUs); 941 } 942 injectSensorDataBase(int handle, float[] values, int accuracy, long timestamp)943 protected int injectSensorDataBase(int handle, float[] values, int accuracy, 944 long timestamp) { 945 return nativeInjectSensorData( 946 mNativeSensorEventQueue, handle, values, accuracy, timestamp); 947 } 948 disableSensor(Sensor sensor)949 private int disableSensor(Sensor sensor) { 950 if (mNativeSensorEventQueue == 0) throw new NullPointerException(); 951 if (sensor == null) throw new NullPointerException(); 952 return nativeDisableSensor(mNativeSensorEventQueue, sensor.getHandle()); 953 } 954 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp)955 protected abstract void dispatchSensorEvent(int handle, float[] values, int accuracy, 956 long timestamp); 957 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispatchFlushCompleteEvent(int handle)958 protected abstract void dispatchFlushCompleteEvent(int handle); 959 960 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues)961 protected void dispatchAdditionalInfoEvent( 962 int handle, int type, int serial, float[] floatValues, int[] intValues) { 963 // default implementation is do nothing 964 } 965 addSensorEvent(Sensor sensor)966 protected abstract void addSensorEvent(Sensor sensor); removeSensorEvent(Sensor sensor)967 protected abstract void removeSensorEvent(Sensor sensor); 968 } 969 970 static final class SensorEventQueue extends BaseEventQueue { 971 private final SensorEventListener mListener; 972 private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>(); 973 SensorEventQueue(SensorEventListener listener, Looper looper, SystemSensorManager manager, String packageName)974 public SensorEventQueue(SensorEventListener listener, Looper looper, 975 SystemSensorManager manager, String packageName) { 976 super(looper, manager, OPERATING_MODE_NORMAL, packageName); 977 mListener = listener; 978 } 979 980 @Override addSensorEvent(Sensor sensor)981 public void addSensorEvent(Sensor sensor) { 982 SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor, 983 mManager.mTargetSdkLevel)); 984 synchronized (mSensorsEvents) { 985 mSensorsEvents.put(sensor.getHandle(), t); 986 } 987 } 988 989 @Override removeSensorEvent(Sensor sensor)990 public void removeSensorEvent(Sensor sensor) { 991 synchronized (mSensorsEvents) { 992 mSensorsEvents.delete(sensor.getHandle()); 993 } 994 } 995 996 // Called from native code. 997 @SuppressWarnings("unused") 998 @Override dispatchSensorEvent(int handle, float[] values, int inAccuracy, long timestamp)999 protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy, 1000 long timestamp) { 1001 final Sensor sensor = mManager.mHandleToSensor.get(handle); 1002 if (sensor == null) { 1003 // sensor disconnected 1004 return; 1005 } 1006 1007 SensorEvent t = null; 1008 synchronized (mSensorsEvents) { 1009 t = mSensorsEvents.get(handle); 1010 } 1011 1012 if (t == null) { 1013 // This may happen if the client has unregistered and there are pending events in 1014 // the queue waiting to be delivered. Ignore. 1015 return; 1016 } 1017 // Copy from the values array. 1018 System.arraycopy(values, 0, t.values, 0, t.values.length); 1019 t.timestamp = timestamp; 1020 t.accuracy = inAccuracy; 1021 t.sensor = sensor; 1022 1023 // call onAccuracyChanged() only if the value changes 1024 final int accuracy = mSensorAccuracies.get(handle); 1025 if (t.accuracy >= 0 && accuracy != t.accuracy) { 1026 mSensorAccuracies.put(handle, t.accuracy); 1027 mListener.onAccuracyChanged(t.sensor, t.accuracy); 1028 } 1029 1030 // Indicate if the discontinuity count changed 1031 t.firstEventAfterDiscontinuity = false; 1032 if (t.sensor.getType() == Sensor.TYPE_HEAD_TRACKER) { 1033 final int lastCount = mSensorDiscontinuityCounts.get(handle); 1034 final int curCount = Float.floatToIntBits(values[6]); 1035 if (lastCount >= 0 && lastCount != curCount) { 1036 mSensorDiscontinuityCounts.put(handle, curCount); 1037 t.firstEventAfterDiscontinuity = true; 1038 } 1039 } 1040 1041 mListener.onSensorChanged(t); 1042 } 1043 1044 // Called from native code. 1045 @SuppressWarnings("unused") 1046 @Override dispatchFlushCompleteEvent(int handle)1047 protected void dispatchFlushCompleteEvent(int handle) { 1048 if (mListener instanceof SensorEventListener2) { 1049 final Sensor sensor = mManager.mHandleToSensor.get(handle); 1050 if (sensor == null) { 1051 // sensor disconnected 1052 return; 1053 } 1054 ((SensorEventListener2) mListener).onFlushCompleted(sensor); 1055 } 1056 return; 1057 } 1058 1059 // Called from native code. 1060 @SuppressWarnings("unused") 1061 @Override dispatchAdditionalInfoEvent( int handle, int type, int serial, float[] floatValues, int[] intValues)1062 protected void dispatchAdditionalInfoEvent( 1063 int handle, int type, int serial, float[] floatValues, int[] intValues) { 1064 if (mListener instanceof SensorEventCallback) { 1065 final Sensor sensor = mManager.mHandleToSensor.get(handle); 1066 if (sensor == null) { 1067 // sensor disconnected 1068 return; 1069 } 1070 SensorAdditionalInfo info = 1071 new SensorAdditionalInfo(sensor, type, serial, intValues, floatValues); 1072 ((SensorEventCallback) mListener).onSensorAdditionalInfo(info); 1073 } 1074 } 1075 } 1076 1077 static final class TriggerEventQueue extends BaseEventQueue { 1078 private final TriggerEventListener mListener; 1079 private final SparseArray<TriggerEvent> mTriggerEvents = new SparseArray<TriggerEvent>(); 1080 TriggerEventQueue(TriggerEventListener listener, Looper looper, SystemSensorManager manager, String packageName)1081 public TriggerEventQueue(TriggerEventListener listener, Looper looper, 1082 SystemSensorManager manager, String packageName) { 1083 super(looper, manager, OPERATING_MODE_NORMAL, packageName); 1084 mListener = listener; 1085 } 1086 1087 @Override addSensorEvent(Sensor sensor)1088 public void addSensorEvent(Sensor sensor) { 1089 TriggerEvent t = new TriggerEvent(Sensor.getMaxLengthValuesArray(sensor, 1090 mManager.mTargetSdkLevel)); 1091 synchronized (mTriggerEvents) { 1092 mTriggerEvents.put(sensor.getHandle(), t); 1093 } 1094 } 1095 1096 @Override removeSensorEvent(Sensor sensor)1097 public void removeSensorEvent(Sensor sensor) { 1098 synchronized (mTriggerEvents) { 1099 mTriggerEvents.delete(sensor.getHandle()); 1100 } 1101 } 1102 1103 // Called from native code. 1104 @SuppressWarnings("unused") 1105 @Override dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp)1106 protected void dispatchSensorEvent(int handle, float[] values, int accuracy, 1107 long timestamp) { 1108 final Sensor sensor = mManager.mHandleToSensor.get(handle); 1109 if (sensor == null) { 1110 // sensor disconnected 1111 return; 1112 } 1113 TriggerEvent t = null; 1114 synchronized (mTriggerEvents) { 1115 t = mTriggerEvents.get(handle); 1116 } 1117 if (t == null) { 1118 Log.e(TAG, "Error: Trigger Event is null for Sensor: " + sensor); 1119 return; 1120 } 1121 1122 // Copy from the values array. 1123 System.arraycopy(values, 0, t.values, 0, t.values.length); 1124 t.timestamp = timestamp; 1125 t.sensor = sensor; 1126 1127 // A trigger sensor is auto disabled. So just clean up and don't call native 1128 // disable. 1129 mManager.cancelTriggerSensorImpl(mListener, sensor, false); 1130 1131 mListener.onTrigger(t); 1132 } 1133 1134 @SuppressWarnings("unused") dispatchFlushCompleteEvent(int handle)1135 protected void dispatchFlushCompleteEvent(int handle) { 1136 } 1137 } 1138 1139 final class InjectEventQueue extends BaseEventQueue { 1140 1141 private int mMode; InjectEventQueue(Looper looper, SystemSensorManager manager, @DataInjectionMode int mode, String packageName)1142 public InjectEventQueue(Looper looper, SystemSensorManager manager, 1143 @DataInjectionMode int mode, String packageName) { 1144 super(looper, manager, mode, packageName); 1145 mMode = mode; 1146 } 1147 injectSensorData(int handle, float[] values, int accuracy, long timestamp)1148 int injectSensorData(int handle, float[] values, int accuracy, long timestamp) { 1149 return injectSensorDataBase(handle, values, accuracy, timestamp); 1150 } 1151 1152 @SuppressWarnings("unused") dispatchSensorEvent(int handle, float[] values, int accuracy, long timestamp)1153 protected void dispatchSensorEvent(int handle, float[] values, int accuracy, 1154 long timestamp) { 1155 } 1156 1157 @SuppressWarnings("unused") dispatchFlushCompleteEvent(int handle)1158 protected void dispatchFlushCompleteEvent(int handle) { 1159 1160 } 1161 1162 @SuppressWarnings("unused") addSensorEvent(Sensor sensor)1163 protected void addSensorEvent(Sensor sensor) { 1164 1165 } 1166 1167 @SuppressWarnings("unused") removeSensorEvent(Sensor sensor)1168 protected void removeSensorEvent(Sensor sensor) { 1169 1170 } 1171 getDataInjectionMode()1172 int getDataInjectionMode() { 1173 return mMode; 1174 } 1175 } 1176 setOperationParameterImpl(SensorAdditionalInfo parameter)1177 protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) { 1178 int handle = -1; 1179 if (parameter.sensor != null) handle = parameter.sensor.getHandle(); 1180 return nativeSetOperationParameter( 1181 mNativeInstance, handle, 1182 parameter.type, parameter.floatValues, parameter.intValues) == 0; 1183 } 1184 isDeviceSensorPolicyDefault(int deviceId)1185 private boolean isDeviceSensorPolicyDefault(int deviceId) { 1186 if (deviceId == DEVICE_ID_DEFAULT) { 1187 return true; 1188 } 1189 if (mVdm == null) { 1190 mVdm = mContext.getSystemService(VirtualDeviceManager.class); 1191 } 1192 return mVdm == null 1193 || mVdm.getDevicePolicy(deviceId, POLICY_TYPE_SENSORS) == DEVICE_POLICY_DEFAULT; 1194 } 1195 1196 /** 1197 * Checks if a sensor should be capped according to HIGH_SAMPLING_RATE_SENSORS 1198 * permission. 1199 * 1200 * This needs to be kept in sync with the list defined on the native side 1201 * in frameworks/native/services/sensorservice/SensorService.cpp 1202 */ isSensorInCappedSet(int sensorType)1203 private boolean isSensorInCappedSet(int sensorType) { 1204 return (sensorType == Sensor.TYPE_ACCELEROMETER 1205 || sensorType == Sensor.TYPE_ACCELEROMETER_UNCALIBRATED 1206 || sensorType == Sensor.TYPE_GYROSCOPE 1207 || sensorType == Sensor.TYPE_GYROSCOPE_UNCALIBRATED 1208 || sensorType == Sensor.TYPE_MAGNETIC_FIELD 1209 || sensorType == Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED); 1210 } 1211 hasHighSamplingRateSensorsPermission()1212 private boolean hasHighSamplingRateSensorsPermission() { 1213 if (!mHasHighSamplingRateSensorsPermission.isPresent()) { 1214 boolean granted = mContext.getPackageManager().checkPermission( 1215 HIGH_SAMPLING_RATE_SENSORS_PERMISSION, 1216 mContext.getApplicationInfo().packageName) == PERMISSION_GRANTED; 1217 mHasHighSamplingRateSensorsPermission = Optional.of(granted); 1218 } 1219 1220 return mHasHighSamplingRateSensorsPermission.get(); 1221 } 1222 } 1223