调用过程中涉及到的文件

Driver:           ft5x0x.cà

HAL:             SensorGTP.cpp  à sensors.cpp  à  SensorDevice.cpp à

Framework:  SensorService.cppàSensorManager.cppà  android_hardware_SensorManager.cpp  à

SensorManager.java à PowerManagerService.java

本文分几个部分:

1、驱动层:tp驱动中实现感应开关

2、HAL层:打开/dev/proximity字符设备,并实现感应开关操作,相当于linux应用程序开发层。

3、framework层:涉及到SensorManager.java与PowerManagerService.java两个文件,主要是负责背光亮灭与sensor开启关闭。

4、app层:主要是PhoneApp接通电话开关感应。

关于android分层架构都应该知道:如下图

第一部分:TP驱动实现距离感应开关实现代码

1、  首先在probe函数中增加一段程序,组要是注册一个混杂字符设备

#include <linux/miscdevice.h>
#include <linux/wakelock.h>
//#include <linux/eventstore.h>
#include <linux/fs.h>
//#include <linux/miscdevice.h>
#include <linux/ioctl.h>#define GTP_PROXIMITY   1 //宏开关
static int gtp_proximity_start = 0;    /* 0 is stop, 1 is start */#define GTP_IOCTL_MAGIC          0x5D
#define GTP_IOCTL_PROX_ON       _IO(GTP_IOCTL_MAGIC, 7)
#define GTP_IOCTL_PROX_OFF      _IO(GTP_IOCTL_MAGIC, 8)
#define FT5X0X_SENSOR_NAME      "gtp_proximity"    //新增字符设备名称#if GTP_PROXIMITY    err = misc_register(>p_proximity_misc);if (err < 0){pr_err("%s: could not register misc device\n", __func__);}
#endifstatic struct miscdevice gtp_proximity_misc = {.minor = MISC_DYNAMIC_MINOR,.name = FT5X0X_SENSOR_NAME,     .fops = >p_proximity_fops,
};static const struct file_operations gtp_proximity_fops = {.owner = THIS_MODULE,.open = FT5X0X_proximity_open,.release = NULL,//_proximity_release,.ioctl = FT5X0X_proximity_ioctl,/*.ioctl = FT5X0x_proximity_ioctl,unlocked_ioctl*/
};static int ft5x0x_proximity_open(struct inode *inode, struct file *file)
{int err;err = nonseekable_open(inode, file);if (err < 0)return err;file->private_data = i2c_get_clientdata(this_client);printk("ft5x0x_proximity_open-file->private_data=%x\r\n",file->private_data);return 0;}
HAL层会根据幻数调用ft5x0x_proximity_ioctl中是否打开距离感应。
static int ft5x0x_proximity_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)
{//printk("ft5x0x_proximity_ioctl");switch (cmd) {case GTP_IOCTL_PROX_ON://gtp_proximity_open();ft5x0x_proximity_set_enable(1);gtp_proximity_start = 1;  /* 0 is stop, 1 is start */printk("ft5x0x_proximity_ioctl--on\r\n");break;case GTP_IOCTL_PROX_OFF://gtp_proximity_release();ft5x0x_proximity_set_enable(0);gtp_proximity_start = 0;printk("ft5x0x_proximity_ioctl--off\r\n");break;default://pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));printk("ft5x0x_proximity_ioctl--error\r\n");return -EINVAL;}return 0;
}

关于如何判断是否接近,可以向FAE咨询,让他们提供说明文档,改哪些寄存器的值实现。

ft5x0x 类型的TP实现:Enable 脸部接近感应功能,拨出电话并且已经开始连线时或者是来电接通电话时启

动此项功能,手机启动触摸IC进入大面积感应发出的I2C指令如下:Write(0xB0,0x01)

操作说明:主控向TP的0xB0 单元写0x01 数据,写入成功后TP即进入脸部接近感应功能;

static void ft5x0x_proximity_set_enable(int enable)
{if(enable == 1){gtp_proximity_start = 1;}else{gtp_proximity_start = 0;}ft5x0x_write_reg(0xB0, enable);
}在probe函数中
INIT_WORK(&ft5x0x_ts->pen_event_work, ft5x0x_ts_pen_irq_work);static void ft5x0x_ts_pen_irq_work(struct work_struct *work)
{
#if 1int ret = -1;
//  printk("==work 1=\n");
#ifdef GTP_PROXIMITYprintk("_ts_pen_irq_work---\r\n");ft5x0x_ts_proximity_work();
#endifret = ft5x0x_read_data();    if (ret == 0) {   ft5x0x_report_value();}
//  else printk("data package read error\n");
//  printk("==work 2=\n");
//      msleep(1);
#endifenable_irq(this_client->irq);}

2,TP当在手机“Enable脸部接近接触感应”模式时:

2.1 听筒端靠近人体距离小于8mm时(具体距离以实测为准),主机端会收到如下数据包:

I2C start +I2C地址+0x00+0xc0+其它相关数据+ I2Cstop(0xc0 是以手势码的形式发出的)

2.2 听筒端移开人体超过8mm时(具体距离以实测为准),主机端会收到如下数据包:

I2C start + I2C地址+0x00+0xe0+其它相关数据+ I2Cstop(0xe0 是以手势码的形式发出的)

3,Disable脸部接近感应(预设) 结束通话时退出大面积感应功能。手机发出的I2C数据:

Write(0xb0,0x00)

操作说明:主机向从机0xb0 地址写0x00数据,写入成功后退出大面积感应功能。

mso- Wat����ily:宋体;mso-fareast-theme-font:minor-fareast;mso-hansi-font-family:Calibri;mso-hansi-theme-font:minor-latin'>开启关闭。

4、app层:主要是PhoneApp接通电话开关感应。

static void ft5x0x_ts_proximity_work(void)
{static int value_temp = 0;int value;char buffer[30]={0};struct ft5x0x_ts_data *data = i2c_get_clientdata(this_client);i2c_smbus_read_i2c_block_data(this_client, 0x00, 8, &(buffer[0]));printk("-ft5x0x_ts_proximity_work-buffer[1] =-%x\n", buffer[1]);if(gtp_proximity_start == 1){if (buffer[1]==0xC0){input_report_abs(data->input_dev, ABS_DISTANCE, 0);     //report far//input_sync(data->input_dev);//value_temp = value;printk("-ft5x0x_ts_proximity_work--near\r\n");}else if(buffer[1]==0xE0){input_report_abs(data->input_dev, ABS_DISTANCE, 1);   //report farprintk("-ft5x0x_ts_proximity_work--far\r\n");}}}在suspend与resume不走tp正常流程。
static void ft5x0x_ts_suspend(struct early_suspend *handler)
{#if GTP_PROXIMITYif (gtp_proximity_start == 1)return;
#endif
… …
}static void ft5x0x_ts_resume(struct early_suspend *handler)
{   printk("==%s==\n", __FUNCTION__);
#if GTP_PROXIMITYif (gtp_proximity_start == 1)return;
#endif… …
}

TP驱动层距离感应已经实现,下一步就是HAL层调用驱动了。

第二部:HAL层实现调用驱动程序,向上层提供接口。

SensorGTP.cpp#include <fcntl.h>
#include <errno.h>
#include <math.h>
#include <poll.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/select.h>#include <cutils/log.h>#include "SensorGTP.h"
#include "sensors.h"#define ft5x0x_DEVICE_NAME                        "/dev/gtp_proximity"   //设备节点
#define GTP_IOCTL_MAGIC                         0x5D
#define GTP_IOCTL_GET_PFLAG                     _IOR(GTP_IOCTL_MAGIC, 1, int)
#define GTP_IOCTL_GET_LFLAG                     _IOR(GTP_IOCTL_MAGIC, 2, int)
#define GTP_IOCTL_SET_PFLAG                     _IOW(GTP_IOCTL_MAGIC, 3, int)
#define GTP_IOCTL_SET_LFLAG                     _IOW(GTP_IOCTL_MAGIC, 4, int)
#define GTP_IOCTL_GET_DATA                      _IOW(GTP_IOCTL_MAGIC, 5, unsigned char)
#define GTP_IOCTL_PROX_ON                                   _IO(GTP_IOCTL_MAGIC, 7)
#define GTP_IOCTL_PROX_OFF                                _IO(GTP_IOCTL_MAGIC, 8)/*****************************************************************************/
SensorGTP::SensorGTP(): SensorBase(ft5x0x_DEVICE_NAME, "ft5x0x_ts"),mEnabled(0),mPendingMask(0),mInputReader(32),mHasPendingEvent(false)
{memset(mPendingEvents, 0, sizeof(mPendingEvents));mPendingEvents[Proximity].version = sizeof(sensors_event_t);mPendingEvents[Proximity].sensor = ID_P;mPendingEvents[Proximity].type = SENSOR_TYPE_PROXIMITY;for (int i=0 ; i<numSensors ; i++)mDelays[i] = 200000000; // 200 ms by default
}SensorGTP::~SensorGTP()
{
}bool SensorGTP::hasPendingEvents() const
{return mHasPendingEvent;
}int SensorGTP::setDelay(int32_t handle, int64_t ns)
{return 0;
}int SensorGTP::setEnable(int32_t handle, int en)
{int what = -1;int cmd;int err = 0;int newState = en ? 1 : 0;switch (handle) {case ID_P: what = Proximity; break;}if (uint32_t(what) >= numSensors)return -EINVAL;if (!mEnabled)open_device();switch (what){case Proximity: //将调用驱动层的ioctol实现开关距离感应if (newState)                    {cmd = GTP_IOCTL_PROX_ON;}else {cmd = GTP_IOCTL_PROX_OFF;}                                break;}int flags = newState;err = ioctl(dev_fd, cmd, &flags);LOGD("ioctl,err=%d\n",err);err = err < 0 ? -errno : 0;LOGD("SensorGTP::enable what=%d; flags=%d; err=%d\n", what, flags, err);LOGE_IF(err, "ECS_IOCTL_APP_SET_XXX failed (%s)", strerror(-err));if (!err){mEnabled &= ~(1 << what);mEnabled |= (uint32_t(flags) << what);}LOGD("SensorGTP::mEnabled=0x%x\n", mEnabled);if (!mEnabled)close_device();return err;
}int SensorGTP::getEnable(int32_t handle)
{int enable=0;int what = -1;switch (handle) {case ID_P: what = Proximity; break;}if (uint32_t(what) >= numSensors)return -EINVAL;enable = mEnabled & (1 << what);if(enable > 0)enable = 1;LOGD("SensorGTP::mEnabled=0x%x; enable=%d\n", mEnabled, enable);return enable;
}int SensorGTP::readEvents(sensors_event_t* data, int count)
{if (count < 1)return -EINVAL;ssize_t n = mInputReader.fill(data_fd);if (n < 0)return n;int numEventReceived = 0;input_event const* event;while (count && mInputReader.readEvent(&event)) {int type = event->type;if (type == EV_ABS) {processEvent(event->code, event->value);mInputReader.next();} else if (type == EV_SYN) {int64_t time = timevalToNano(event->time);for (int j=0 ; count && mPendingMask && j<numSensors ; j++) {if (mPendingMask & (1<<j)) {mPendingMask &= ~(1<<j);mPendingEvents[j].timestamp = time;if (mEnabled & (1<<j)) {*data++ = mPendingEvents[j];count--;numEventReceived++;}}}if (!mPendingMask) {mInputReader.next();}} else {LOGE("Apds9900Sensor: unknown event (type=%d, code=%d)",type, event->code);mInputReader.next();}}return numEventReceived;
}void SensorGTP::processEvent(int code, int value)
{switch (code) {case EVENT_TYPE_PROXIMITY:mPendingMask |= 1<<Proximity;mPendingEvents[Proximity].distance = value;LOGD("SensorGTP: mPendingEvents[Proximity].distance = %f",mPendingEvents[Proximity].distance);break;        default:LOGD("SensorGTP: default value = %d",value);break;}
}
SensorGTP.h
#ifndef ANDROID_GTP_SENSOR_H
#define ANDROID_GTP_SENSOR_H#include <stdint.h>
#include <errno.h>
#include <sys/cdefs.h>
#include <sys/types.h>#include "sensors.h"
#include "SensorBase.h"
#include "InputEventReader.h"/*****************************************************************************/struct input_event;class SensorGTP : public SensorBase
{
public:SensorGTP();virtual ~SensorGTP();enum{Light   = 0,Proximity   = 1,numSensors};virtual int setDelay(int32_t handle, int64_t ns);virtual int setEnable(int32_t handle, int enabled);virtual bool hasPendingEvents() const;virtual int readEvents(sensors_event_t* data, int count);virtual int getEnable(int32_t handle);void processEvent(int code, int value);
private:int update_delay();uint32_t mEnabled;bool mHasPendingEvent;uint32_t mPendingMask;InputEventCircularReader mInputReader;sensors_event_t mPendingEvents[numSensors];uint64_t mDelays[numSensors];
};/*****************************************************************************/#endif  // ANDROID_GT8XX_SENSOR_H

此函数初始化将在sensors.cpp函数中实现,关于此阶段的说明,先来看下SensorDevice.cpp文件中的函数,此文件中实现了SensorDevice的初始化并且通过

hw_get_module(SENSORS_HARDWARE_MODULE_ID,(hw_module_tconst**)&mSensorModule);获取sensor模块,将sensor打开。

SensorDevice::SensorDevice():  mSensorDevice(0),mSensorModule(0)
{status_t err = hw_get_module(SENSORS_HARDWARE_MODULE_ID,(hw_module_t const**)&mSensorModule);LOGE_IF(err, "couldn't load %s module (%s)",SENSORS_HARDWARE_MODULE_ID, strerror(-err));if (mSensorModule) {err = sensors_open(&mSensorModule->common, &mSensorDevice);
//1、此函数将会调用sensors.cpp文件中的open_sensors函数。LOGE_IF(err, "couldn't open device for module %s (%s)",SENSORS_HARDWARE_MODULE_ID, strerror(-err));if (mSensorDevice) {sensor_t const* list;
//2、此函数将调用sensors.cpp中的sensors__get_sensors_list函数。 ssize_t count = mSensorModule->get_sensors_list(mSensorModule, &list);mActivationCount.setCapacity(count);Info model;for (size_t i=0 ; i<size_t(count) ; i++) {mActivationCount.add(list[i].handle, model);mSensorDevice->activate(mSensorDevice, list[i].handle, 0);//3、}}}
}
在上面一个函数标志1中函数将会调用:
struct sensors_module_t HAL_MODULE_INFO_SYM = {common: {tag: HARDWARE_MODULE_TAG,version_major: 1,version_minor: 0,id: SENSORS_HARDWARE_MODULE_ID,name: "AKM Sensor module",author: "Asahi Kasei Microdevices",methods: &sensors_module_methods,},get_sensors_list: sensors__get_sensors_list,
};static struct hw_module_methods_t sensors_module_methods = {open: open_sensors
};static int open_sensors(const struct hw_module_t* module, const char* id,struct hw_device_t** device)
{int status = -EINVAL;//new 一个sensors_poll_context_t并初始化sensors_poll_context_t *dev = new sensors_poll_context_t();memset(&dev->device, 0, sizeof(sensors_poll_device_t));dev->device.common.tag = HARDWARE_DEVICE_TAG;dev->device.common.version  = 0;dev->device.common.module   = const_cast<hw_module_t*>(module);dev->device.common.close    = poll__close;dev->device.activate        = poll__activate;dev->device.setDelay        = poll__setDelay;dev->device.poll            = poll__poll;*device = &dev->device.common;status = 0;return status;
}
在sensors_poll_context_t *dev = new sensors_poll_context_t();函数中sensors_poll_context_t::sensors_poll_context_t()
{//new 并初始化SensorGTP()mSensors[gtp_proximity] = new SensorGTP();mPollFds[gtp_proximity].fd = mSensors[gtp_proximity]->getFd();mPollFds[gtp_proximity].events = POLLIN;mPollFds[gtp_proximity].revents = 0;int wakeFds[2];int result = pipe(wakeFds);LOGE_IF(result<0, "error creating wake pipe (%s)", strerror(errno));fcntl(wakeFds[0], F_SETFL, O_NONBLOCK);fcntl(wakeFds[1], F_SETFL, O_NONBLOCK);mWritePipeFd = wakeFds[1];mPollFds[wake].fd = wakeFds[0];mPollFds[wake].events = POLLIN;mPollFds[wake].revents = 0;
}3、在上一个函数中mSensorDevice->activate(mSensorDevice, list[i].handle, 0);
此函数调用了:
int sensors_poll_context_t::activate(int handle, int enabled) {
/*将根据handle返回哪个sensor。Handle有ID_A:acc;ID_M:ID_O:mag;ID_L:ID_P:
gtp_proximity; al3006_pls;*/int drv = handleToDriver(handle); int err;err = mSensors[drv]->setEnable(handle, enabled);if (enabled && !err) {const char wakeMessage(WAKE_MESSAGE);int result = write(mWritePipeFd, &wakeMessage, 1);LOGE_IF(result<0, "error sending wake message (%s)", strerror(errno));}return err;
}err = mSensors[drv]->setEnable(handle, enabled);
将调用int SensorGTP::setEnable(int32_t handle, int en)使能距离感应。现在分析第二部分中的第2步:
SensorService.cppSensorManager.cpp  android_hardware_SensorManager.cpp
—> SensorManager.java 在SensorService.cpp中初始化SensorDevice是在如下函数中:
void SensorService::onFirstRef()
{LOGD("nuSensorService starting...");SensorDevice& dev(SensorDevice::getInstance());在SensorManager.cpp中
SensorManager::SensorManager(): mSensorList(0)
{//获取sensorservice服务const String16 name("sensorservice");while (getService(name, &mSensorServer) != NO_ERROR) {usleep(250000);}//获取sensor项mSensors = mSensorServer->getSensorList();size_t count = mSensors.size();mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));for (size_t i=0 ; i<count ; i++) {mSensorList[i] = mSensors.array() + i;}
}JNI层android_hardware_SensorManager.cpp
framework层SensorManager.java在PowerManagerService.java中public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,WorkSource ws) {
… …if (isScreenLock(flags)) {// if this causes a wakeup, we reactivate all of the locks and// set it to whatever they want.  otherwise, we modulate that// by the current state so we never turn it more on than// it already is.if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {mProximityWakeLockCount++;if (mProximityWakeLockCount == 1) {enableProximityLockLocked();//打开距离感应函数}} else {if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {int oldWakeLockState = mWakeLockState;mWakeLockState = mLocks.reactivateScreenLocksLocked();// Disable proximity sensor if if user presses power key while we are in the// "waiting for proximity sensor to go negative" state.if ((mWakeLockState & SCREEN_ON_BIT) != 0&& mProximitySensorActive && mProximityWakeLockCount == 0) {mProximitySensorActive = false;}if (mSpew) {Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)+ " mWakeLockState=0x"+ Integer.toHexString(mWakeLockState)+ " previous wakeLockState=0x"+ Integer.toHexString(oldWakeLockState));}} else {if (mSpew) {Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)+ " mLocks.gatherState()=0x"+ Integer.toHexString(mLocks.gatherState())+ " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));}mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();}setPowerState(mWakeLockState | mUserState);}}else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {if (newlock) {mPartialCount++;if (mPartialCount == 1) {if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);}}Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME);}在函数中private void enableProximityLockLocked() {if (mDebugProximitySensor) {Slog.d(TAG, "enableProximityLockLocked");}if (!mProximitySensorEnabled) {// clear calling identity so sensor manager battery stats are accuratelong identity = Binder.clearCallingIdentity();try {//注册监听器mProximityListenermSensorManager.registerListener(mProximityListener, mProximitySensor,SensorManager.SENSOR_DELAY_NORMAL);mProximitySensorEnabled = true;} finally {Binder.restoreCallingIdentity(identity);}}}在函数中SensorEventListener mProximityListener = new SensorEventListener() {public void onSensorChanged(SensorEvent event) {long milliseconds = SystemClock.elapsedRealtime();synchronized (mLocks) {float distance = event.values[0];long timeSinceLastEvent = milliseconds - mLastProximityEventTime;mLastProximityEventTime = milliseconds;mHandler.removeCallbacks(mProximityTask);boolean proximityTaskQueued = false;// compare against getMaximumRange to support sensors that only return 0 or 1//比较接近距离,是否开启感应(0< distance < 5 cm&&)boolean active = (distance >= 0.0 && distance < PROXIMITY_THRESHOLD &&distance < mProximitySensor.getMaximumRange());if (mDebugProximitySensor) {Slog.d(TAG, "mProximityListener.onSensorChanged active: " + active);}if (timeSinceLastEvent < PROXIMITY_SENSOR_DELAY) {// enforce delaying atleast PROXIMITY_SENSOR_DELAY before processingmProximityPendingValue = (active ? 1 : 0);mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);proximityTaskQueued = true;} else {// process the value immediatelymProximityPendingValue = -1;proximityChangedLocked(active);//改变距离感应状态}// update mProximityPartialLock stateboolean held = mProximityPartialLock.isHeld();if (!held && proximityTaskQueued) {// hold wakelock until mProximityTask runsmProximityPartialLock.acquire();} else if (held && !proximityTaskQueued) {mProximityPartialLock.release();}}}public void onAccuracyChanged(Sensor sensor, int accuracy) {// ignore}};将会进入private void proximityChangedLocked(boolean active) {if (mDebugProximitySensor) {Slog.d(TAG, "proximityChangedLocked, active: " + active);}if (!mProximitySensorEnabled) {Slog.d(TAG, "Ignoring proximity change after sensor is disabled");return;}if (active) {if (mDebugProximitySensor) {Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="+ mProxIgnoredBecauseScreenTurnedOff);}if (!mProxIgnoredBecauseScreenTurnedOff) {//会进入此函数goToSleepLocked(SystemClock.uptimeMillis(),WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);}mProximitySensorActive = true;} else {// proximity sensor negative events trigger as user activity.// temporarily set mUserActivityAllowed to true so this will work// even when the keyguard is on.mProximitySensorActive = false;if (mDebugProximitySensor) {Slog.d(TAG, "b mProxIgnoredBecauseScreenTurnedOff="+ mProxIgnoredBecauseScreenTurnedOff);}if (!mProxIgnoredBecauseScreenTurnedOff) {forceUserActivityLocked();}if (mProximityWakeLockCount == 0) {// disable sensor if we have no listeners left after proximity negativedisableProximityLockLocked();}}}private void goToSleepLocked(long time, int reason) {if (mLastEventTime <= time) {mLastEventTime = time;// cancel all of the wake locksmWakeLockState = SCREEN_OFF;int N = mLocks.size();int numCleared = 0;boolean proxLock = false;for (int i=0; i<N; i++) {WakeLock wl = mLocks.get(i);if (isScreenLock(wl.flags)) {if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)&& reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {proxLock = true;} else {mLocks.get(i).activated = false;numCleared++;}}}if (!proxLock) {mProxIgnoredBecauseScreenTurnedOff = true;if (mDebugProximitySensor) {Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");}}EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);mStillNeedSleepNotification = true;mUserState = SCREEN_OFF;//设置供电状态setPowerState(SCREEN_OFF, false, reason);cancelTimerLocked();}}

上述阶段是指LCD背光开灭状态控制。

下面来分析最后一个阶段PhoneApp如何调用。

在OnCreate()中// Wake lock used to control proximity sensor behavior.if ((pm.getSupportedWakeLockFlags()& PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) != 0x0) {mProximityWakeLock =pm.newWakeLock(PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, LOG_TAG);}if (DBG) Log.d(LOG_TAG, "onCreate: mProximityWakeLock: " + mProximityWakeLock);// create mAccelerometerListener only if we are using the proximity sensorif (proximitySensorModeEnabled()) {mAccelerometerListener = new AccelerometerListener(this, this);}/* package */ void setBeginningCall(boolean beginning) {// Note that we are beginning a new call, for proximity sensor supportmBeginningCall = beginning;// Update the Proximity sensor based on mBeginningCall state//更新距离感应状态updateProximitySensorMode(mCM.getState());}/* package */ void updateProximitySensorMode(Phone.State state) {if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: state = " + state);if (proximitySensorModeEnabled()) {synchronized (mProximityWakeLock) {// turn proximity sensor off and turn screen on immediately if// we are using a headset, the keyboard is open, or the device// is being held in a horizontal position.boolean screenOnImmediately = (isHeadsetPlugged()|| PhoneUtils.isSpeakerOn(this)|| ((mBtHandsfree != null) && mBtHandsfree.isAudioOn())|| mIsHardKeyboardOpen);// We do not keep the screen off when we are horizontal, but we do not force it// on when we become horizontal until the proximity sensor goes negative.
//                boolean horizontal = (mOrientation == AccelerometerListener.ORIENTATION_HORIZONTAL);
//                && !horizontalif ((((!PhoneUtils.isVideoCall()) && (state == Phone.State.OFFHOOK)) || mBeginningCall) && !screenOnImmediately ) {// Phone is in use!  Arrange for the screen to turn off// automatically when the sensor detects a close object.if (!mProximityWakeLock.isHeld()) {if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: acquiring...");//注意此函数mProximityWakeLock.acquire();} else {if (VDBG) Log.d(LOG_TAG, "updateProximitySensorMode: lock already held.");}} else {// Phone is either idle, or ringing.  We don't want any// special proximity sensor behavior in either case.if (mProximityWakeLock.isHeld()) {if (DBG) Log.d(LOG_TAG, "updateProximitySensorMode: releasing...");// Wait until user has moved the phone away from his head if we are// releasing due to the phone call ending.// Qtherwise, turn screen on immediatelyint flags =(screenOnImmediately ? 0 : PowerManager.WAIT_FOR_PROXIMITY_NEGATIVE);mProximityWakeLock.release(flags);} else {if (VDBG) {Log.d(LOG_TAG, "updateProximitySensorMode: lock already released.");}}}}}}mProximityWakeLock.acquire();将调用PowerManagerService.java中的        public void acquire() {if (!mRefCounted || mCount++ == 0) {long ident = Binder.clearCallingIdentity();try {PowerManagerService.this.acquireWakeLockLocked(mFlags, mToken,MY_UID, MY_PID, mTag, null);mHeld = true;} finally {Binder.restoreCallingIdentity(ident);}}}然后调用public void acquireWakeLockLocked(int flags, IBinder lock, int uid, int pid, String tag,WorkSource ws) {… …if (isScreenLock(flags)) {// if this causes a wakeup, we reactivate all of the locks and// set it to whatever they want.  otherwise, we modulate that// by the current state so we never turn it more on than// it already is.if ((flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK) {mProximityWakeLockCount++;if (mProximityWakeLockCount == 1) {enableProximityLockLocked();}} else {if ((wl.flags & PowerManager.ACQUIRE_CAUSES_WAKEUP) != 0) {int oldWakeLockState = mWakeLockState;mWakeLockState = mLocks.reactivateScreenLocksLocked();if (mSpew) {Slog.d(TAG, "wakeup here mUserState=0x" + Integer.toHexString(mUserState)+ " mWakeLockState=0x"+ Integer.toHexString(mWakeLockState)+ " previous wakeLockState=0x"+ Integer.toHexString(oldWakeLockState));}} else {if (mSpew) {Slog.d(TAG, "here mUserState=0x" + Integer.toHexString(mUserState)+ " mLocks.gatherState()=0x"+ Integer.toHexString(mLocks.gatherState())+ " mWakeLockState=0x" + Integer.toHexString(mWakeLockState));}mWakeLockState = (mUserState | mWakeLockState) & mLocks.gatherState();}setPowerState(mWakeLockState | mUserState);}}else if ((flags & LOCK_MASK) == PowerManager.PARTIAL_WAKE_LOCK) {if (newlock) {mPartialCount++;if (mPartialCount == 1) {if (LOG_PARTIAL_WL) EventLog.writeEvent(EventLogTags.POWER_PARTIAL_WAKE_STATE, 1, tag);}}Power.acquireWakeLock(Power.PARTIAL_WAKE_LOCK,PARTIAL_NAME);}
… …
}

既上面所说的。至此tp从底层驱动到上层app整个流程分析完毕。

android TP实现距离感应相关推荐

  1. 通话距离感应实现源码

    展讯平台:android 7.0代码. packages/apps/Dialer/InCallUI/src/com/android/incallui/ProximitySensor.java fram ...

  2. 什么是“蓝牙距离感应装置”

    mtk6573在过CTA的时候,有一个"蓝牙距离感应装置".这个和CTA 版本没有关系. (客戶也沒有回報過CTA 因此項而fail 的) "这是BT4.0 ,需要两只手 ...

  3. Android下的重力感应应用

    android手机支持重力感应,针对Android的通过如下接口支持: android.hardware.SensorEventListener 该接口有两个方法需要实现: @Override  pu ...

  4. Android5.1 修改距离感应的阈值

    在Android5.1 修改距离感应的阈值,主要修改两个参数: .ps_threshold_high = 200, .ps_threshold_low = 110, 程序中 ~/mt6735/kern ...

  5. iOS关闭自动锁屏和距离感应

    ##关闭自动锁屏 [UIApplication sharedApplication].idleTimerDisabled = YES; 复制代码 ##关闭距离感应(防止黑屏) [UIDevice cu ...

  6. android 移植 距离感应,Android sensors移植文档

    1  硬件工作原理 1.1 G-sensor主要管脚定义 上图是LIS3DHTR在TD_100中的原理图 l 电压:VDD:sensor的供电电源. VDD_IO:sensor的IO电源. l 中断: ...

  7. android TP

    转载至: http://blog.csdn.net/xubin341719/article/details/7820492 向作者致予最崇高的敬意!!! android 电容屏(一):电容屏基本原理篇 ...

  8. 用android studio测量距离,Android studio 百度地图开发(6)Marker绑定事件、计算两点距离...

    Android studio 百度地图开发(6)Marker绑定事件.计算两点距离 email:chentravelling@163.com 开发环境:win7 64位,Android Studio, ...

  9. Android 根据sensor重力感应 app横竖屏旋转

    在app开发中,当系统禁止自动旋转以后,app需要横竖屏旋转该怎么做呢,那就只能根据sensor 重力感应的值来实现屏幕旋转了 1.获取sensor重力感应的值 import android.hard ...

最新文章

  1. iOS base64 MD5
  2. 数据结构与算法分析-第一章Java类(04)
  3. mac idea用自带的maven还是_苹果电脑自带截图工具怎么用?mac自带截屏工具使用技巧分享
  4. c++内存管理优化之ptmalloc,tcmalloc,jemalloc使用实例
  5. Ubuntu 安装SVN服务器端
  6. 删除360浏览器新标签页内的热词导航
  7. 51nod-动物与游戏【树链剖分,线段树】
  8. Apache Flink 在京东的实践与优化
  9. 故意向Linux内核提交漏洞被全线拉黑?华人教授行为引众怒
  10. 条件锁pthread_cond_t 的应用
  11. 工业软件深度:中国PLM/MES/SCADA/DCS格局与主要玩家分析~
  12. NASA数据批量下载——wget
  13. 室内环境空气质量监测系统
  14. Aqara绿米董事长游延筠专访:以用户体验为出发点,打造更懂你的家
  15. Python软件的下载安装教程
  16. Mysql隐式类型转换
  17. wps插入入html,WPS文字技巧—如何在WPS文字中快速插入域
  18. 知道创宇的爬虫面试题
  19. 帝国cms 操作整理
  20. 使用Servlet3.0上传图片,无法使用part.getSubmittedFileName()方法解决

热门文章

  1. 智慧水产养殖解决方案
  2. Zygote启动流程及源码分析
  3. 数字信号处理matlab心得,数字信号处理学习心得体会3篇
  4. 智慧校园平台源码 智慧教务 智慧电子班牌系统
  5. R语言实现LDA主题模型分析网购数据
  6. ChemOffice.
  7. 我都30了,还能不能做软件测试?
  8. 对于application对象的认识
  9. text-shadow和文字颜色渐变冲突问题
  10. 宏基微型计算机c650使用方法,C650型卧式普通车床课程设计.docx