Home | History | Annotate | Download | only in util
      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 
     17 package com.android.systemui.util;
     18 
     19 import android.hardware.HardwareBuffer;
     20 import android.hardware.Sensor;
     21 import android.hardware.SensorAdditionalInfo;
     22 import android.hardware.SensorDirectChannel;
     23 import android.hardware.SensorEventListener;
     24 import android.hardware.SensorManager;
     25 import android.hardware.TriggerEventListener;
     26 import android.os.Handler;
     27 import android.os.HandlerThread;
     28 import android.os.MemoryFile;
     29 import android.util.Log;
     30 
     31 import com.android.internal.annotations.VisibleForTesting;
     32 import com.android.internal.util.Preconditions;
     33 
     34 import java.util.List;
     35 
     36 /**
     37  * Wrapper around sensor manager that hides potential sources of latency.
     38  *
     39  * Offloads fetching (non-dynamic) sensors and (un)registering listeners onto a background thread
     40  * without blocking. Note that this means registering listeners now always appears successful even
     41  * if it is not.
     42  */
     43 public class AsyncSensorManager extends SensorManager {
     44 
     45     private static final String TAG = "AsyncSensorManager";
     46 
     47     private final SensorManager mInner;
     48     private final List<Sensor> mSensorCache;
     49     private final HandlerThread mHandlerThread = new HandlerThread("async_sensor");
     50     @VisibleForTesting final Handler mHandler;
     51 
     52     public AsyncSensorManager(SensorManager inner) {
     53         mInner = inner;
     54         mHandlerThread.start();
     55         mHandler = new Handler(mHandlerThread.getLooper());
     56         mSensorCache = mInner.getSensorList(Sensor.TYPE_ALL);
     57     }
     58 
     59     @Override
     60     protected List<Sensor> getFullSensorList() {
     61         return mSensorCache;
     62     }
     63 
     64     @Override
     65     protected List<Sensor> getFullDynamicSensorList() {
     66         return mInner.getDynamicSensorList(Sensor.TYPE_ALL);
     67     }
     68 
     69     @Override
     70     protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs,
     71             Handler handler, int maxReportLatencyUs, int reservedFlags) {
     72         mHandler.post(() -> {
     73             if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) {
     74                 Log.e(TAG, "Registering " + listener + " for " + sensor + " failed.");
     75             }
     76         });
     77         return true;
     78     }
     79 
     80     @Override
     81     protected boolean flushImpl(SensorEventListener listener) {
     82         return mInner.flush(listener);
     83     }
     84 
     85     @Override
     86     protected SensorDirectChannel createDirectChannelImpl(MemoryFile memoryFile,
     87             HardwareBuffer hardwareBuffer) {
     88         throw new UnsupportedOperationException("not implemented");
     89     }
     90 
     91     @Override
     92     protected void destroyDirectChannelImpl(SensorDirectChannel channel) {
     93         throw new UnsupportedOperationException("not implemented");
     94     }
     95 
     96     @Override
     97     protected int configureDirectChannelImpl(SensorDirectChannel channel, Sensor s, int rate) {
     98         throw new UnsupportedOperationException("not implemented");
     99     }
    100 
    101     @Override
    102     protected void registerDynamicSensorCallbackImpl(DynamicSensorCallback callback,
    103             Handler handler) {
    104         mHandler.post(() -> mInner.registerDynamicSensorCallback(callback, handler));
    105     }
    106 
    107     @Override
    108     protected void unregisterDynamicSensorCallbackImpl(DynamicSensorCallback callback) {
    109         mHandler.post(() -> mInner.unregisterDynamicSensorCallback(callback));
    110     }
    111 
    112     @Override
    113     protected boolean requestTriggerSensorImpl(TriggerEventListener listener, Sensor sensor) {
    114         mHandler.post(() -> {
    115             if (!mInner.requestTriggerSensor(listener, sensor)) {
    116                 Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed.");
    117             }
    118         });
    119         return true;
    120     }
    121 
    122     @Override
    123     protected boolean cancelTriggerSensorImpl(TriggerEventListener listener, Sensor sensor,
    124             boolean disable) {
    125         Preconditions.checkArgument(disable);
    126 
    127         mHandler.post(() -> {
    128             if (!mInner.cancelTriggerSensor(listener, sensor)) {
    129                 Log.e(TAG, "Canceling " + listener + " for " + sensor + " failed.");
    130             }
    131         });
    132         return true;
    133     }
    134 
    135     @Override
    136     protected boolean initDataInjectionImpl(boolean enable) {
    137         throw new UnsupportedOperationException("not implemented");
    138     }
    139 
    140     @Override
    141     protected boolean injectSensorDataImpl(Sensor sensor, float[] values, int accuracy,
    142             long timestamp) {
    143         throw new UnsupportedOperationException("not implemented");
    144     }
    145 
    146     @Override
    147     protected boolean setOperationParameterImpl(SensorAdditionalInfo parameter) {
    148         mHandler.post(() -> mInner.setOperationParameter(parameter));
    149         return true;
    150     }
    151 
    152     @Override
    153     protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
    154         mHandler.post(() -> {
    155             if (sensor == null) {
    156                 mInner.unregisterListener(listener);
    157             } else {
    158                 mInner.unregisterListener(listener, sensor);
    159             }
    160         });
    161     }
    162 }
    163