android TP实现距离感应

调用过程中涉及到的文件

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__);
    }
#endif

static 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 1
	int ret = -1;
//	printk("==work 1=\n");
#ifdef GTP_PROXIMITY
	printk("_ts_pen_irq_work---\r\n");
	ft5x0x_ts_proximity_work();
#endif
	ret = ft5x0x_read_data();	
	if (ret == 0) {	
		ft5x0x_report_value();
	}
//	else printk("data package read error\n");
//	printk("==work 2=\n");
//    	msleep(1);
#endif
    enable_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 far
			printk("-ft5x0x_ts_proximity_work--far\r\n");
		}
	}}


在suspend与resume不走tp正常流程。
static void ft5x0x_ts_suspend(struct early_suspend *handler)
{
	#if GTP_PROXIMITY
	    if (gtp_proximity_start == 1)
		return;
#endif
… …
}


static void ft5x0x_ts_resume(struct early_suspend *handler)
{	
	printk("==%s==\n", __FUNCTION__);
#if GTP_PROXIMITY
    if (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 accurate
            long identity = Binder.clearCallingIdentity();
            try {
			//注册监听器mProximityListener
                mSensorManager.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 processing
                    mProximityPendingValue = (active ? 1 : 0);
                    mHandler.postDelayed(mProximityTask, PROXIMITY_SENSOR_DELAY - timeSinceLastEvent);
                    proximityTaskQueued = true;
                } else {
                    // process the value immediately
                    mProximityPendingValue = -1;
                    proximityChangedLocked(active);//改变距离感应状态
                }

                // update mProximityPartialLock state
                boolean held = mProximityPartialLock.isHeld();
                if (!held && proximityTaskQueued) {
                    // hold wakelock until mProximityTask runs
                    mProximityPartialLock.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 negative
                disableProximityLockLocked();
            }
        }
    }


    private void goToSleepLocked(long time, int reason) {

        if (mLastEventTime <= time) {
            mLastEventTime = time;
            // cancel all of the wake locks
            mWakeLockState = 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 sensor
            if (proximitySensorModeEnabled()) {
                mAccelerometerListener = new AccelerometerListener(this, this);
            }


    /* package */ void setBeginningCall(boolean beginning) {
        // Note that we are beginning a new call, for proximity sensor support
        mBeginningCall = 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);
//                && !horizontal
                if ((((!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 immediately
                      	  int 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实现距离感应)