• Android SensorManager学习


    SensorManager

    在SensorManager.java文件的开头,有一段sensor应用的示例。应用层获取sensor的数据主要是通过SensorManager的onAccuracyChanged和onSensorChanged两个监听接口。

    public class SensorActivity extends Activity, implements SensorEventListener {
      private final SensorManager mSensorManager;
      private final Sensor mAccelerometer;
     
      public SensorActivity() {
          mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
          mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
      }
     
      protected void onResume() {
          super.onResume();
          mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
      }
     
      protected void onPause() {
          super.onPause();
          mSensorManager.unregisterListener(this);
      }
     
      public void onAccuracyChanged(Sensor sensor, int accuracy) {
      }
     
      public void onSensorChanged(SensorEvent event) {
      } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    代码路径:frameworks/base/core/java/android/hardware/SensorManager.java,SensorManager类主要是对外提供sensor的调用接口:getDefaultSensor,registerListener,unregisterListener。从下面的代码里可以看到,这三个接口会调用getFullSensorList,registerListenerImpl,unregisterListenerImpl。实际实现的代码在SystemSensorManager.java里。

    public Sensor getDefaultSensor(int type) {
        // TODO: need to be smarter, for now, just return the 1st sensor
        // 这里是从所有的sensor中获得对应type的sensor list.
        List<Sensor> l = getSensorList(type);
        boolean wakeUpSensor = false;
        // For the following sensor types, return a wake-up sensor. These types are by default
        // defined as wake-up sensors. For the rest of the SDK defined sensor types return a
        // non_wake-up version.
        // 如果获取的tyep是以下类型,则返回一个wake-up sensor,否则返回non_wake-up sensor。
        if (type == Sensor.TYPE_PROXIMITY || type == Sensor.TYPE_SIGNIFICANT_MOTION
                || type == Sensor.TYPE_TILT_DETECTOR || type == Sensor.TYPE_WAKE_GESTURE
                || type == Sensor.TYPE_GLANCE_GESTURE || type == Sensor.TYPE_PICK_UP_GESTURE
                || type == Sensor.TYPE_WRIST_TILT_GESTURE
                || type == Sensor.TYPE_DYNAMIC_SENSOR_META || type == Sensor.TYPE_HINGE_ANGLE) {
            wakeUpSensor = true;
        }
    
        for (Sensor sensor : l) {
            if (sensor.isWakeUpSensor() == wakeUpSensor) return sensor;
        }
        return null;
    }
    public List<Sensor> getSensorList(int type) {
        // cache the returned lists the first time
        List<Sensor> list;
        // 获取所有sensor
        final List<Sensor> fullList = getFullSensorList();
        synchronized (mSensorListByType) {
            // 查看mSensorListByType缓存里有没有要组成的sensor,如果有的话直接返回
            list = mSensorListByType.get(type);
            if (list == null) {
                if (type == Sensor.TYPE_ALL) {
                    list = fullList;
                } else {
                    list = new ArrayList<Sensor>();
                    for (Sensor i : fullList) {
                        // 遍历所有sensor,找到对应type的sensor
                        if (i.getType() == type) {
                            list.add(i);
                        }
                    }
                }
                // Collections.unmodifiableList用于构造一个不能修改的List
                list = Collections.unmodifiableList(list);
                // 存入mSensorListByType缓存
                mSensorListByType.append(type, list);
            }
        }
        return list;
    }
    public boolean registerListener(SensorEventListener listener, Sensor sensor,
                                    int samplingPeriodUs) {
        return registerListener(listener, sensor, samplingPeriodUs, null);
    }
    public boolean registerListener(SensorEventListener listener, Sensor sensor,
                                    int samplingPeriodUs, Handler handler) {
        int delay = getDelay(samplingPeriodUs);
        return registerListenerImpl(listener, sensor, delay, handler, 0, 0);
    }
    private static int getDelay(int rate) {
        int delay = -1;
        switch (rate) {
            case SENSOR_DELAY_FASTEST:
                delay = 0;
                break;
            case SENSOR_DELAY_GAME:
                delay = 20000;
                break;
            case SENSOR_DELAY_UI:
                delay = 66667;
                break;
            case SENSOR_DELAY_NORMAL:
                delay = 200000;
                break;
            default:
                delay = rate;
                break;
        }
        return delay;
    }
    public void unregisterListener(SensorEventListener listener) {
        if (listener == null) {
            return;
        }
        unregisterListenerImpl(listener, null);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86

    代码路径:frameworks/base/core/java/android/hardware/SystemSensorManager.java,SystemSensorManager继承SensorManager,完成getFullSensorList,registerListenerImpl,unregisterListenerImpl接口。

    private final HashMap<SensorEventListener, SensorEventQueue> mSensorListeners =
                new HashMap<SensorEventListener, SensorEventQueue>();
    
    protected List<Sensor> getFullSensorList() {
    	return mFullSensorsList;
    }
    public SystemSensorManager(Context context, Looper mainLooper) {
    	synchronized (sLock) {
    		if (!sNativeClassInited) {
    			sNativeClassInited = true;
    			nativeClassInit();
    		}
    	}
    
    	mMainLooper = mainLooper;
    	mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
    	mContext = context;
    	mNativeInstance = nativeCreate(context.getOpPackageName());
    
    	// initialize the sensor list
    	for (int index = 0;; ++index) {
    		Sensor sensor = new Sensor();
    		if (!nativeGetSensorAtIndex(mNativeInstance, sensor, index)) break;
    		mFullSensorsList.add(sensor);
    		mHandleToSensor.put(sensor.getHandle(), sensor);
    	}
    }
    protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,
    	int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {
        android.util.SeempLog.record_sensor_rate(381, sensor, delayUs);
        if (listener == null || sensor == null) {
            Log.e(TAG, "sensor or listener is null");
            return false;
        }
        // Trigger Sensors should use the requestTriggerSensor call.
        if (sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
            Log.e(TAG, "Trigger Sensors should use the requestTriggerSensor.");
            return false;
        }
        if (maxBatchReportLatencyUs < 0 || delayUs < 0) {
            Log.e(TAG, "maxBatchReportLatencyUs and delayUs should be non-negative");
            return false;
        }
        if (mSensorListeners.size() >= MAX_LISTENER_COUNT) {
            throw new IllegalStateException("register failed, "
                + "the sensor listeners size has exceeded the maximum limit "
                + MAX_LISTENER_COUNT);
    	}
    
    // Invariants to preserve:
    // - one Looper per SensorEventListener
    // - one Looper per SensorEventQueue
    // We map SensorEventListener to a SensorEventQueue, which holds the looper
        synchronized (mSensorListeners) {
            // 从缓存mSensorListeners里获取listener
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue == null) {
                Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;
                final String fullClassName =
                        listener.getClass().getEnclosingClass() != null
                            ? listener.getClass().getEnclosingClass().getName()
                            : listener.getClass().getName();
                // 新建一个SensorEventQueue
                queue = new SensorEventQueue(listener, looper, this, fullClassName);
                // 添加sensor
                if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {
                    queue.dispose();
                    return false;
                }
                // 将listener和queue存到缓存mSensorListeners中
                mSensorListeners.put(listener, queue);
                return true;
            } else {
                return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);
            }
        }
    }
    
    /** @hide */
    @Override
    protected void unregisterListenerImpl(SensorEventListener listener, Sensor sensor) {
        android.util.SeempLog.record_sensor(382, sensor);
        // Trigger Sensors should use the cancelTriggerSensor call.
        if (sensor != null && sensor.getReportingMode() == Sensor.REPORTING_MODE_ONE_SHOT) {
            return;
        }
    
        synchronized (mSensorListeners) {
            SensorEventQueue queue = mSensorListeners.get(listener);
            if (queue != null) {
                boolean result;
                if (sensor == null) {
                    result = queue.removeAllSensors();
                } else {
                    result = queue.removeSensor(sensor, true);
                }
                if (result && !queue.hasSensors()) {
                    mSensorListeners.remove(listener);
                    queue.dispose();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    在registerListenerImpl函数里面,若之前该SensorEventListener(由应用自己创建)没有创建过SensorEventQueue,那么创建一个,并和SensorEventListener一起添加到mSensorListeners,当创建SensorEventQueue时,会同时构造一个其父类对象BaseEventQueue

    static final class SensorEventQueue extends BaseEventQueue {
        private final SensorEventListener mListener;
        private final SparseArray mSensorsEvents = new SparseArray();
    
        public SensorEventQueue(SensorEventListener listener, Looper looper,
                SystemSensorManager manager, String packageName) {
            // 调用父类方法
            super(looper, manager, OPERATING_MODE_NORMAL, packageName);
            mListener = listener;
        }
    
        ......
      
        // Called from native code.
    	@SuppressWarnings("unused")
    	@Override
        // 数据分发,调用onAccuracyChanged,onSensorChanged
    	protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,
    			long timestamp) {
    		final Sensor sensor = mManager.mHandleToSensor.get(handle);
    		if (sensor == null) {
    			// sensor disconnected
    			return;
    		}
    
    		SensorEvent t = null;
    		synchronized (mSensorsEvents) {
    			t = mSensorsEvents.get(handle);
    		}
    
    		if (t == null) {
    			// This may happen if the client has unregistered and there are pending events in
    			// the queue waiting to be delivered. Ignore.
    			return;
    		}
    		// Copy from the values array.
    		System.arraycopy(values, 0, t.values, 0, t.values.length);
    		t.timestamp = timestamp;
    		t.accuracy = inAccuracy;
    		t.sensor = sensor;
    
    		// call onAccuracyChanged() only if the value changes
    		final int accuracy = mSensorAccuracies.get(handle);
    		if ((t.accuracy >= 0) && (accuracy != t.accuracy)) {
    			mSensorAccuracies.put(handle, t.accuracy);
                // 回调应用重写的onAccuracyChanged
    			mListener.onAccuracyChanged(t.sensor, t.accuracy);
    		}
            // 回调应用重写的onSensorChanged
    		mListener.onSensorChanged(t);
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    接着在其nativeInitBaseEventQueue()方法里边,通过jni调用android/frameworks/base/core/jni/android_hardware_SensorManager.cpp nativeInitSensorEventQueue()中创建一个接收数据的Receiver对象,这个之后分析数据如何给上来再详细分析。

    接着看注册流程,然后,通过BaseEventQueue::addSensor()将注册一个sensor的流程继续往下走,

    public boolean addSensor(Sensor sensor, int delayUs, int maxBatchReportLatencyUs) {
    	// Check if already present.
    	int handle = sensor.getHandle();
    	if (mActiveSensors.get(handle)) return false;
    
    	// Get ready to receive events before calling enable.
    	mActiveSensors.put(handle, true);
    	addSensorEvent(sensor);
    	if (enableSensor(sensor, delayUs, maxBatchReportLatencyUs) != 0) {
    		// Try continuous mode if batching fails.
    		if (maxBatchReportLatencyUs == 0
    				|| maxBatchReportLatencyUs > 0 && enableSensor(sensor, delayUs, 0) != 0) {
    			removeSensor(sensor, false);
    			return false;
    		}
    	}
    	return true;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    通过BaseEventQueue::enableSensor()继续往下走,

    private int enableSensor(Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
    	if (mNativeSensorEventQueue == 0) throw new NullPointerException();
    	if (sensor == null) throw new NullPointerException();
    	return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
    			maxBatchReportLatencyUs);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    通过jni调用C++的接口,android/frameworks/base/core/jni/android_hardware_SensorManager.cpp

    static jint nativeEnableSensor(JNIEnv *env, jclass clazz, jlong eventQ, jint handle, jint rate_us,
    							   jint maxBatchReportLatency) {
    	sp receiver(reinterpret_cast(eventQ));
    	return receiver->getSensorEventQueue()->enableSensor(handle, rate_us, maxBatchReportLatency,
    														 0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    接下来到了 android/frameworks/native/libs/sensor/SensorEventQueue.cpp

    status_t SensorEventQueue::enableSensor(int32_t handle, int32_t samplingPeriodUs,
    										int64_t maxBatchReportLatencyUs, int reservedFlags) const {
    	return mSensorEventConnection->enableDisable(handle, true, us2ns(samplingPeriodUs),
    												 us2ns(maxBatchReportLatencyUs), reservedFlags);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    接着就到了 android/frameworks/native/services/sensorservice/SensorEventConnection.cpp

    status_t SensorService::SensorEventConnection::enableDisable(
    		int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
    		int reservedFlags)
    {
    	status_t err;
    	if (enabled) {
    		err = mService->enable(this, handle, samplingPeriodNs, maxBatchReportLatencyNs,
    							   reservedFlags, mOpPackageName);
    
    	} else {
    		err = mService->disable(this, handle);
    	}
    	return err;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    接下去就是android/frameworks/native/services/sensorservice/SensorService.cpp SensorService::enable()

    status_t SensorService::enable(const sp& connection,
    		int handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags,
    		const String16& opPackageName) {
    	if (mInitCheck != NO_ERROR)
    		return mInitCheck;
    
    	sp sensor = getSensorInterfaceFromHandle(handle);
    	if (sensor == nullptr ||
    		!canAccessSensor(sensor->getSensor(), "Tried enabling", opPackageName)) {
    		return BAD_VALUE;
    	}
    
    	ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
    	if (mCurrentOperatingMode != NORMAL
    		   && !isWhiteListedPackage(connection->getPackageName())) {
    		return INVALID_OPERATION;
    	}
    
    	SensorRecord* rec = mActiveSensors.valueFor(handle);
    	if (rec == nullptr) {
    		rec = new SensorRecord(connection);
    		mActiveSensors.add(handle, rec);
    		if (sensor->isVirtual()) {
    			mActiveVirtualSensors.emplace(handle);
    		}
    
    		// There was no SensorRecord for this sensor which means it was previously disabled. Mark
    		// the recent event as stale to ensure that the previous event is not sent to a client. This
    		// ensures on-change events that were generated during a previous sensor activation are not
    		// erroneously sent to newly connected clients, especially if a second client registers for
    		// an on-change sensor before the first client receives the updated event. Once an updated
    		// event is received, the recent events will be marked as current, and any new clients will
    		// immediately receive the most recent event.
    		if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
    			auto logger = mRecentEvent.find(handle);
    			if (logger != mRecentEvent.end()) {
    				logger->second->setLastEventStale();
    			}
    		}
    	} else {
    		if (rec->addConnection(connection)) {
    			// this sensor is already activated, but we are adding a connection that uses it.
    			// Immediately send down the last known value of the requested sensor if it's not a
    			// "continuous" sensor.
    			if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
    				// NOTE: The wake_up flag of this event may get set to
    				// WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
    
    				auto logger = mRecentEvent.find(handle);
    				if (logger != mRecentEvent.end()) {
    					sensors_event_t event;
    					// Verify that the last sensor event was generated from the current activation
    					// of the sensor. If not, it is possible for an on-change sensor to receive a
    					// sensor event that is stale if two clients re-activate the sensor
    					// simultaneously.
    					if(logger->second->populateLastEventIfCurrent(&event)) {
    						event.sensor = handle;
    						if (event.version == sizeof(sensors_event_t)) {
    							if (isWakeUpSensorEvent(event) && !mWakeLockAcquired) {
    								setWakeLockAcquiredLocked(true);
    							}
    							connection->sendEvents(&event, 1, nullptr);
    							if (!connection->needsWakeLock() && mWakeLockAcquired) {
    								checkWakeLockStateLocked(&connLock);
    							}
    						}
    					}
    				}
    			}
    		}
    	}
    
    	if (connection->addSensor(handle)) {
    		BatteryService::enableSensor(connection->getUid(), handle);
    		// the sensor was added (which means it wasn't already there)
    		// so, see if this connection becomes active
    		mConnectionHolder.addEventConnectionIfNotPresent(connection);
    	} else {
    		ALOGW("sensor %08x already enabled in connection %p (ignoring)",
    			handle, connection.get());
    	}
    
    	// Check maximum delay for the sensor.
    	nsecs_t maxDelayNs = sensor->getSensor().getMaxDelay() * 1000LL;
    	if (maxDelayNs > 0 && (samplingPeriodNs > maxDelayNs)) {
    		samplingPeriodNs = maxDelayNs;
    	}
    
    	nsecs_t minDelayNs = sensor->getSensor().getMinDelayNs();
    	if (samplingPeriodNs < minDelayNs) {
    		samplingPeriodNs = minDelayNs;
    	}
    
    	ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d"
    								"rate=%" PRId64 " timeout== %" PRId64"",
    			 handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
    
    	status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs,
    								 maxBatchReportLatencyNs);
    
    	// Call flush() before calling activate() on the sensor. Wait for a first
    	// flush complete event before sending events on this connection. Ignore
    	// one-shot sensors which don't support flush(). Ignore on-change sensors
    	// to maintain the on-change logic (any on-change events except the initial
    	// one should be trigger by a change in value). Also if this sensor isn't
    	// already active, don't call flush().
    	if (err == NO_ERROR &&
    			sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
    			rec->getNumConnections() > 1) {
    		connection->setFirstFlushPending(handle, true);
    		status_t err_flush = sensor->flush(connection.get(), handle);
    		// Flush may return error if the underlying h/w sensor uses an older HAL.
    		if (err_flush == NO_ERROR) {
    			rec->addPendingFlushConnection(connection.get());
    		} else {
    			connection->setFirstFlushPending(handle, false);
    		}
    	}
    
    	if (err == NO_ERROR) {
    		ALOGD_IF(DEBUG_CONNECTIONS, "Calling activate on %d", handle);
    		err = sensor->activate(connection.get(), true);
    	}
    
    	if (err == NO_ERROR) {
    		connection->updateLooperRegistration(mLooper);
    
    		if (sensor->getSensor().getRequiredPermission().size() > 0 &&
    				sensor->getSensor().getRequiredAppOp() >= 0) {
    			connection->mHandleToAppOp[handle] = sensor->getSensor().getRequiredAppOp();
    		}
    
    		mLastNSensorRegistrations.editItemAt(mNextSensorRegIndex) =
    				SensorRegistrationInfo(handle, connection->getPackageName(),
    									   samplingPeriodNs, maxBatchReportLatencyNs, true);
    		mNextSensorRegIndex = (mNextSensorRegIndex + 1) % SENSOR_REGISTRATIONS_BUF_SIZE;
    	}
    
    	if (err != NO_ERROR) {
    		// batch/activate has failed, reset our state.
    		cleanupWithoutDisableLocked(connection, handle);
    	}
    	return err;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    接下来看android/frameworks/native/services/sensorservice/SensorInterface.cpp

    status_t HardwareSensor::activate(void* ident, bool enabled) {
    	return mSensorDevice.activate(ident, mSensor.getHandle(), enabled);
    }
    
    • 1
    • 2
    • 3

    接下来看android/frameworks/native/services/sensorservice/SensorDevice.cpp

    status_t SensorDevice::activate(void* ident, int handle, int enabled) {
    	if (mSensors == nullptr) return NO_INIT;
    
    	Mutex::Autolock _l(mLock);
    	return activateLocked(ident, handle, enabled);
    }
    
    status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
    	bool activateHardware = false;
    
    	status_t err(NO_ERROR);
    
    	ssize_t activationIndex = mActivationCount.indexOfKey(handle);
    	if (activationIndex < 0) {
    		ALOGW("Handle %d cannot be found in activation record", handle);
    		return BAD_VALUE;
    	}
    	Info& info(mActivationCount.editValueAt(activationIndex));
    
    	ALOGD_IF(DEBUG_CONNECTIONS,
    			 "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
    			 ident, handle, enabled, info.batchParams.size());
    
    	if (enabled) {
    		ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
    
    		if (isClientDisabledLocked(ident)) {
    			ALOGE("SensorDevice::activate, isClientDisabledLocked(%p):true, handle:%d",
    					ident, handle);
    			return INVALID_OPERATION;
    		}
    
    		if (info.batchParams.indexOfKey(ident) >= 0) {
    			if (info.numActiveClients() > 0 && !info.isActive) {
    				activateHardware = true;
    			}
    		} else {
    			// Log error. Every activate call should be preceded by a batch() call.
    			ALOGE("\t >>>ERROR: activate called without batch");
    		}
    	} else {
    		ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
    
    		// If a connected dynamic sensor is deactivated, remove it from the
    		// dictionary.
    		auto it = mConnectedDynamicSensors.find(handle);
    		if (it != mConnectedDynamicSensors.end()) {
    			delete it->second;
    			mConnectedDynamicSensors.erase(it);
    		}
    
    		if (info.removeBatchParamsForIdent(ident) >= 0) {
    			if (info.numActiveClients() == 0) {
    				// This is the last connection, we need to de-activate the underlying h/w sensor.
    				activateHardware = true;
    			} else {
    				// Call batch for this sensor with the previously calculated best effort
    				// batch_rate and timeout. One of the apps has unregistered for sensor
    				// events, and the best effort batch parameters might have changed.
    				ALOGD_IF(DEBUG_CONNECTIONS,
    						 "\t>>> actuating h/w batch 0x%08x %" PRId64 " %" PRId64, handle,
    						 info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
    				checkReturn(mSensors->batch(
    						handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
    			}
    		} else {
    			// sensor wasn't enabled for this ident
    		}
    
    		if (isClientDisabledLocked(ident)) {
    			return NO_ERROR;
    		}
    	}
    
    	if (activateHardware) {
    		err = doActivateHardwareLocked(handle, enabled);
    
    		if (err != NO_ERROR && enabled) {
    			// Failure when enabling the sensor. Clean up on failure.
    			info.removeBatchParamsForIdent(ident);
    		} else {
    			// Update the isActive flag if there is no error. If there is an error when disabling a
    			// sensor, still set the flag to false since the batch parameters have already been
    			// removed. This ensures that everything remains in-sync.
    			info.isActive = enabled;
    		}
    	}
    
    	return err;
    }
    status_t SensorDevice::doActivateHardwareLocked(int handle, bool enabled) {
        ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
                 enabled);
        status_t err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
        ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
                 strerror(-err));
        return err;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98

    接下来通过hidl,到了HAL,先到android 自己实现的hal层,就称它为android sensor hal吧,后面再往下手机厂家自己实现的hal层称为oem sensor hal 咯,

    这边也是直接往下看流程,后面会再分析一下android sensor hal的启动,android/hardware/interfaces/sensors/1.0/default/Sensors.cpp

    Return Sensors::activate(
    		int32_t sensor_handle, bool enabled) {
    	return ResultFromStatus(
    			mSensorDevice->activate(
    				reinterpret_cast(mSensorDevice),
    				sensor_handle,
    				enabled));
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    接着到了android/hardware/libhardware/modules/sensors/multihal.cpp

    static int device__activate(struct sensors_poll_device_t *dev, int handle,
    		int enabled) {
    	sensors_poll_context_t* ctx = (sensors_poll_context_t*) dev;
    	return ctx->activate(handle, enabled);
    }
    int sensors_poll_context_t::activate(int handle, int enabled) {
        int retval = -EINVAL;
        ALOGV("activate");
        int local_handle = get_local_handle(handle);
        sensors_poll_device_t* v0 = this->get_v0_device_by_handle(handle);
        if (halIsCompliant(this, handle) && local_handle >= 0 && v0) {
            retval = v0->activate(v0, local_handle, enabled);
        } else {
            ALOGE("IGNORING activate(enable %d) call to non-API-compliant sensor handle=%d !",
                    enabled, handle);
        }
        ALOGV("retval %d", retval);
        return retval;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    这边再下去就是厂家自己实现的接口了,android的部分到此为止

    1 . Android calls sensors_open()
    2 . A sensors hal obiect is created
    a.The sensors hal sends lookup requests to the SSC about all known data types.
    b.The sensor object is created when an SUID is available for a data type.
    i.Sensor attributes are queried and stored in sensor object
    ii.A sensor t object is populated using the attributesc . A list of available sensors is populated in sensors hal
    3 . Android calls get_sensors_list().
    a . A list of available sensors is returned
    4 . Android calls batch ()
    a . The sensors hal finds a sensor corresponding to the handleb . This sensor is configured with new parameterssensor is active . a new config request is sent
    5 . Android calls activatea .
    a.The sensors hal finds a sensor corresponding to the handle.
    b . If this sensor is activated , a new ssc_connection ( ) is made and config request is sent.
    c . If this sensor is deactivated . a ssc_connection is closed
    6 . Android calls poll
    a. A sensors hal returns available events
    7.Android calls flush ()
    a.A sensors hal finds a sensor corresponding to the handle
    b . Calls sensor.flush ()
    i.The sensor sends a flush request to the SSC

  • 相关阅读:
    如何翻译图片上的英文?建议收藏这三个方法
    JVM调优工具
    基于springboot垃圾分类管理系统
    通过API接口进行商品价格监控,可以按照以下步骤进行操作
    无文件恶意软件攻击是什么意思?
    在 Java 中 new 一个对象的流程是怎样的
    [MoeCTF 2023]——Web方向详细Write up、Re、Misc、Crypto部分Writeup
    React之受控组件和非受控组件以及高阶组件
    Spring IOC 容器:掌握 Spring 的核心技术
    寻找最小覆盖子串 - LeetCode 76
  • 原文地址:https://blog.csdn.net/haofeng_ma/article/details/122425872