sensor:gsensor的流程以及优化分析


概述


frameworks\base\core\java\android\view\WindowOrientationListener.java


监听sensor是否有数据变化

首先看看芯片方向(x,y,z):

补充流程:

PhoneWindowManager调用updateOrientationListenerLp去SensorManager里面去注册一个Listener,

当Sensor发生变化的时候,PhoneWindowManager就可以监听到并且调用回调onProposeRotationChanged。

Callback
如下:

1
MyOrientationListener.onProposeRotationChange 
PhoneWindowManager.java

-------------》

class MyOrientationListener extends
WindowOrientationListener {

@Override

public void
onProposedRotationChanged(introtation) {

if (localLOGV) Log.v(TAG,"onProposedRotationChanged, rotation=" + rotation);

updateRotation(false);

}

}

--------》

2. PhoneWindowManager.updateRotation(booleanalwaysSendConfiguration)

void
updateRotation(booleanalwaysSendConfiguration) {

try {

//set orientation on WindowManager

mWindowManager.updateRotation(alwaysSendConfiguration, false);、、WindowManagerService的对象

} catch (RemoteException e) {

// Ignore

}

}

3. WindowManagerService.updateRotation(booleanalwaysSendConfiguration, boolean forceRelayout)

二代码分析

public void
onSensorChanged(SensorEvent event) {

// The vector given in theSensorEvent points straight up (towards the sky) under ideal

// conditions (the phone is notaccelerating).  I‘ll call this up vectorelsewhere.

float x =event.values[ACCELEROMETER_DATA_X];

float y =event.values[ACCELEROMETER_DATA_Y];

float z =event.values[ACCELEROMETER_DATA_Z];

if (LOG) {

Slog.v(TAG, "Rawacceleration vector: "

+ "x=" + x +", y=" + y + ", z=" + z

+ ",magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));

}

// Apply a low-pass filter to theacceleration up vector in cartesian space.

// Reset the orientation listenerstate if the samples are too far apart in time

// or when we see values of (0, 0,0) which indicates that we polled the

// accelerometer too soon afterturning it on and we don‘t have any data yet.

final long now = event.timestamp;

final long then =mLastFilteredTimestampNanos;

final float timeDeltaMS = (now -then) * 0.000001f;

final boolean skipSample;

if (now < then

|| now > then +MAX_FILTER_DELTA_TIME_NANOS

|| (x == 0 && y ==0 && z == 0)) {

if (LOG) {

Slog.v(TAG, "Resettingorientation listener.");

}

reset();

skipSample = true;

} else {

final float alpha = timeDeltaMS/ (FILTER_TIME_CONSTANT_MS + timeDeltaMS);

x = alpha * (x -mLastFilteredX) + mLastFilteredX;

y = alpha * (y -mLastFilteredY) + mLastFilteredY;

z = alpha * (z -mLastFilteredZ) + mLastFilteredZ;

if (LOG) {

Slog.v(TAG, "Filteredacceleration vector: "

+ "x=" +x + ", y=" + y + ", z=" + z

+ ",magnitude=" + FloatMath.sqrt(x * x + y * y + z * z));

}

skipSample = false;

}

mLastFilteredTimestampNanos = now;

mLastFilteredX = x;

mLastFilteredY = y;

mLastFilteredZ = z;

boolean isAccelerating = false;

boolean isFlat = false;

boolean isSwinging = false;

if (!skipSample) {

// Calculate the magnitude ofthe acceleration vector.

final float magnitude =FloatMath.sqrt(x * x + y * y + z * z);

if (magnitude <NEAR_ZERO_MAGNITUDE) {

if (LOG) {

Slog.v(TAG,"Ignoring sensor data, magnitude too close to zero.");

}

clearPredictedRotation();

} else {

// Determine whether thedevice appears to be undergoing external acceleration.

if(isAccelerating(magnitude)) {

isAccelerating = true;

mAccelerationTimestampNanos = now;

}

// Calculate the tiltangle.

// This is the anglebetween the up vector and the x-y plane (the plane of

// the screen) in a rangeof [-90, 90] degrees.

//   -90 degrees: screen horizontal and facingthe ground (overhead)

//     0 degrees: screen vertical

//    90 degrees: screen horizontal and facingthe sky (on table)

final int
tiltAngle = (int) Math.round(//关键数据1:tiltAngle
 计算出传感器的倾斜角

Math.asin(z /magnitude) * RADIANS_TO_DEGREES);

addTiltHistoryEntry(now,
tiltAngle);

// Determine whether thedevice appears to be flat or swinging.

if (isFlat(now)) {

isFlat = true;

mFlatTimestampNanos =now;

}

if (isSwinging(now,tiltAngle)) {

isSwinging = true;

mSwingTimestampNanos =now;

}

// If the tilt angle is tooclose to horizontal then we cannot determine

// the orientation angle ofthe screen.

if (Math.abs(tiltAngle)> MAX_TILT) {

if (LOG) {

Slog.v(TAG,"Ignoring sensor data, tilt angle too high: "

+"tiltAngle=" + tiltAngle);

}

clearPredictedRotation();

} else {

// Calculate theorientation angle.

// This is the anglebetween the x-y projection of the up vector onto

// the +y-axis,increasing clockwise in a range of [0, 360] degrees.

int
orientationAngle = (int) Math.round(//关键数据2:计算出方向
角度

-Math.atan2(-x,y) * RADIANS_TO_DEGREES);

if (orientationAngle < 0) {

// atan2 returns[-180, 180]; normalize to [0, 360]

orientationAngle +=360;

}

// Find the nearestrotation.

int
nearestRotation = (orientationAngle+ 45) / 90;

//关键数据3:计算出要旋转的方向;也就是说orientationAngle
需要大于45
才会找到一个方向(共四个方向:0,1,2,3

if (nearestRotation ==4) {

nearestRotation =0;

}

// Determine the predicted orientation.
判断预报的方向:mPredictedRotation是否合理

if (isTiltAngleAcceptable(nearestRotation,tiltAngle)

&&
isOrientationAngleAcceptable(nearestRotation,

orientationAngle)) {

updatePredictedRotation(now, nearestRotation);

if (LOG) {

Slog.v(TAG,"Predicted: "

+"tiltAngle=" + tiltAngle

+", orientationAngle=" + orientationAngle

+", predictedRotation=" + mPredictedRotation

+", predictedRotationAgeMS="

+ ((now - mPredictedRotationTimestampNanos)

* 0.000001f));

}

} else{////所以做好不要进入
无效数据范围

if (LOG) {

Slog.v(TAG,"Ignoring sensor data, no predicted rotation: "

+"tiltAngle=" + tiltAngle

+", orientationAngle=" + orientationAngle);

}

clearPredictedRotation();

}

}

}

}

// Determine new proposedrotation.判断新的建议的方向:mProposedRotation
是否合理

final int oldProposedRotation =
mProposedRotation;

if (mPredictedRotation < 0 ||
isPredictedRotationAcceptable(now)) {

mProposedRotation = mPredictedRotation;//关键数:4:新的建议方向等于预报方向。

}

// Write final statistics aboutwhere we are in the orientation detection process.

if (LOG) {

Slog.v(TAG, "Result: currentRotation=" +mOrientationListener.mCurrentRotation

+ ",proposedRotation=" + mProposedRotation

+ ",predictedRotation=" + mPredictedRotation

+ ",timeDeltaMS=" + timeDeltaMS

+ ",isAccelerating=" + isAccelerating

+ ", isFlat="+ isFlat

+ ",isSwinging=" + isSwinging

+ ",timeUntilSettledMS=" + remainingMS(now,

mPredictedRotationTimestampNanos + PROPOSAL_SETTLE_TIME_NANOS)

+ ",timeUntilAccelerationDelayExpiredMS=" + remainingMS(now,

mAccelerationTimestampNanos +PROPOSAL_MIN_TIME_SINCE_ACCELERATION_ENDED_NANOS)

+ ",timeUntilFlatDelayExpiredMS=" + remainingMS(now,

mFlatTimestampNanos + PROPOSAL_MIN_TIME_SINCE_FLAT_ENDED_NANOS)

+ ",timeUntilSwingDelayExpiredMS=" + remainingMS(now,

mSwingTimestampNanos + PROPOSAL_MIN_TIME_SINCE_SWING_ENDED_NANOS));

}

// Tell the listener.

if (mProposedRotation!= oldProposedRotation &&
mProposedRotation>= 0) {

if (LOG) {

Slog.v(TAG, "Proposedrotation changed! proposedRotation=" + mProposedRotation

+ ",oldProposedRotation=" + oldProposedRotation);

}

mOrientationListener.onProposedRotationChanged(mProposedRotation);

/*通知windoweservice去更新rotation*/

}

}

2.1    
mOrientationListener.onProposedRotationChanged(mProposedRotation);

MyOrientationListener.onProposeRotationChange
----------

PhoneWindowManager.java

class MyOrientationListener extendsWindowOrientationListener {

@Override

public void
onProposedRotationChanged(introtation) {

if (localLOGV) Log.v(TAG,"onProposedRotationChanged, rotation=" + rotation);

updateRotation(false);

}

}

三  
关键结构:

1.        private static finalint[][]TILT_TOLERANCE
= new int[][]{

参数含义:{旋转方向(0,90,180,270), 倾斜角}

/* ROTATION_0   */ { -25, 70 },

/* ROTATION_90  */ { -25, 65 },

/* ROTATION_180 */ { -25, 60 },

/* ROTATION_270 */ { -25, 65 }

};

也就是tiltAngle在各个倾斜角的范围;

2.这里有两个关键的方向:

原来方向oldProposedRotation
 等于
mProposedRotation

预报方向mPredictedRotation   
等于
nearestRotation

 建议方向
mProposedRotation
  如果条件满足等于
mPredictedRotation   

3.总的来说是否更新rotation到listenser
需要如下的条件(从Tell the listener往前推理)优化如下几个条件:

条件1):(mProposedRotation
!= oldProposedRotation &&
mProposedRotation >= 0)

条件2):新的预报方向
是否可以作为
建议方向的条件是:if (mPredictedRotation < 0
|| isPredictedRotationAcceptable(now))

其中两个

isPredictedRotationAcceptable():是判断预报方向的在某时间内是否稳定;//可以缩短其时间
提高灵敏度

mPredictedRotation
<0 : 说明tiltAngle和orientationAngle
都不在合理的范围内

条件3):所以tiltAngle和orientationAngle
不要进入
无效数据范围。可以调整TILT_TOLERANCEADJACENT_ORIENTATION_ANGLE_GAP
齿槽角(目前是45度)

isOrientationAngleAcceptable()//该函数会判断相邻方向之间的齿槽角差距

Case 1

// For example, if currentRotation is ROTATION_0(则rotation=0) and
proposed is ROTATION_90(则rotation=1),

// then we want tocheck
orientationAngle > 45 + GAP / 2.也就是最低的方向角下限

if (currentRotation>= 0) {

// If the specified rotation isthe same or is counter-clockwise adjacent

// to the current rotation,then we set a lower bound on the orientation angle.

// For example, ifcurrentRotation is ROTATION_0 and proposed is ROTATION_90,

// then we want to checkorientationAngle > 45 + GAP / 2.

if (rotation == currentRotation

|| rotation ==(currentRotation + 1) % 4) {

int lowerBound = rotation * 90 - 45+ADJACENT_ORIENTATION_ANGLE_GAP / 2; //lowerBound
:最低下限

if (rotation == 0) {

if (orientationAngle>= 315 && orientationAngle < lowerBound + 360) {

return false;

}

} else {

if (orientationAngle< lowerBound) {

return false;

}

}

}

所以说ADJACENT_ORIENTATION_ANGLE_GAP
越大,lowerBound 就越大,orientationAngle
就会越容易满足条件,

Case 2

//If the specified rotation is the same or is clockwise adjacent,

// then we set an upper boundon the orientation angle.

// For example, ifcurrentRotation is ROTATION_0 and rotation is ROTATION_270(则rotation=3)
,

// then we want to checkorientationAngle < 315 - GAP / 2.

if (rotation == currentRotation

|| rotation ==(currentRotation + 3) % 4) {

int
upperBound = rotation * 90 + 45-
ADJACENT_ORIENTATION_ANGLE_GAP/ 2;

if (rotation == 0) {

if (orientationAngle<= 45 && orientationAngle > upperBound) {

return false;

}

} else {

if (orientationAngle> upperBound) {

return false;

}

}

}

所以说ADJACENT_ORIENTATION_ANGLE_GAP
越小,upperBound
就越大,orientationAngle就会越容易满足条件,

条件4):nearestRotation
要发生变化

条件5):以调整转屏角度及转屏加速度delay方面的设置来达到些许优化转屏速度的目的

在函数:private boolean isPredictedRotationAcceptable(long now){}里面的时间

四 FAQ

1.客户有如下需求:

需校正重力感应角度,將機器放於桌面,用手托住機器一側,慢慢向上抬起,當機器後殼與桌面夾角角度達到45度時,畫面應能出現旋轉(四個方向都必須是到達45度角後才能旋轉)

--------

改变屏幕旋转的角度,可以修改frameworks/base/core/java/android/view/WindowOrientationListener.java中的MAX_TILT或者TILT_TOLERANCE

但是这样修改之后的影响不确定。

时间: 2024-10-23 09:04:02

sensor:gsensor的流程以及优化分析的相关文章

6.流程类优化

网优四大部分优化 覆盖类优化 容量类优化 功率类优化(干扰类优化) 流程类优化 按照流程的步骤,一步步分析优化,与流程相关的优化 入网初始接入,重入网,切换,寻呼,位置更新等 所有制式的状态,发生的变化都是类似的. 空闲状态rrc idle 连接状态rrc connected 状态转移 都是伴随信令交互来变化的 非正常驻留:没有CM卡,只能拨打紧急电话 寻呼:为了快速做业务时入网的定义 业务流程(信令) 常见:入网(开机驻留),接入(做业务),切换,位置更新 小区选择(最优信号排序,记忆优先),

在Ceph中创建虚拟机流程改进之分析

作为个人学习笔记分享,有任何问题欢迎交流! 最近在Gerrit中看到一个change:https://review.openstack.org/#/c/94295/ , 它主要是对当前在Ceph中创建虚拟机的流程的改进.如果glance的backend是ceph, 则nova创建虚拟机到RBD的流程是这样的: 通过glance从ceph中下载image --> 本地 --> 复制image到rbd 这个change的目的就是:不需要下载到本地,直接在rbd中复制image,以提高虚拟机创建的速

Swift 性能探索和优化分析

Swift 性能探索和优化分析 Apple 在推出 Swift 时就将其冠以先进,安全和高效的新一代编程语言之名.前两点在 Swift 的语法和语言特性中已经表现得淋漓尽致:像是尾随闭包,枚举关联值,可选值和强制的类型安全等都是 Swift 显而易见的优点.但是对于高效一点,就没有那么明显了.在 2014 年 WWDC 大会上 Apple 宣称 Swift 具有超越 Objective-C 的性能,甚至某些情况下可以媲美和超过 C.但是在 Swift 正式发布后,很多开发者发现似乎 Swift

前端优化分析 之 javascript引用位置优化

在很多优化法则中都提到,尽量将javascript放到页面底部,这是为什么呢 我通过firebug进行了下简单的分析 看下图  本页面首尾都存在javascript代码 我们分析得出 1.整个页面文档家在结束才开始加载css和js以及其他的数据 2.当顶部的所有js都家在结束之后才可以加载页面中的图片 3.顶部的common.css和common.js几乎是同时开始加载 4.底部的loader-min.js和离他最近的footer.jpg也是同时开始加载 由此,我们可以分析出,至少在这个版本的f

用FineReport报表系统构建ITIL流程系统变更分析

用FineReport报表系统构建ITIL流程系统变更分析 注:此文为"帆软十年,项册征集"活动的获奖作品. 一.应用背景 随着ITIL的发展和深入,为提高IT服务管理的质量,某银行上线一套符合ITIL的流程工具,其中涉及事件.问题.测试.变更管理等流程,上线后,有效地控制了运营管理中各流程环节的质量,提高了整体效率,为收集和展现电子流程化管理效果,量化考核指标,需提高报表展现效果和报表效率,以前的报表软件对excl支持不够,且图形不能导出,而这正是FineReport报表工具的优势.

支付宝app支付java后台流程及原理分析

java版支付宝app支付流程及原理分析 本实例是基于springmvc框架编写     一.流程步骤         1.执行流程           当手机端app(就是你公司开发的app)在支付页面时,调起服务端(后台第1个创建订单接口)接口,后台把需要调起支付宝支付的参数返回给手机端,手机端拿到         这些参数后,拉起支付宝支付环境完成支付,完成支付后会调异步通知(第2个接口),此时需要给支付宝返回成功或者失败信息,成功后会调用同步通知(第3个接口)         返回支付成

Mysql 索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别. MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵

mySql索引优化分析

MySQL索引优化分析 为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义.助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句.还在等啥子?撸起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别.MongoDB是NoSQL中的一种.NoSQL的全称是Not only SQL,非关系型数据库.它的特点是性能高,扩张性强,模式灵活

256模板网网站优化分析之站长工具篇

之前我们发布的一篇文章 "256模板官网站点SEO优化分析记录"记录了网站一些基本的排名情况,以及网站收录.快照等情况.通过对上一次网站截图的对比,我们发现了百度对256模板网的收录速度还是挺快的,做到了当天就可以收录的速度,大体上还是比较满意,下面我们来具体分析一下. 经过对比我们发现有如下内容: 1.网站快照 网站首页的快照有些慢,显示是在24号的快照,估计是首页更新的内容有些少,以为我们只是更新了一篇文章,看来要努力添加文章了. 2.关键词排名 通过对比我们发现www.25625