在调试光感传感器(android2.2)发现,传递过来的light value值是驱动值,但是实现的亮度变到最亮后却没有改变,查看代码发现如下问题

1:mIsDocked何时改变

powerManagerService.java(framwork/base/services/java/com/android/server/)

lightSensorChangedLocked(){

.........

int lcdValue = getAutoBrightnessValue(
//(mIsDocked ? value : mHighestLightSensorValue), //因为这里mIsDocked的缘故
value,
mLcdBacklightValues);

}

private void dockStateChanged(int state) {
synchronized (mLocks) {

//在这里改变的
mIsDocked = (state != Intent.EXTRA_DOCK_STATE_UNDOCKED);
if (mIsDocked) {
mHighestLightSensorValue = -1;
}
if ((mPowerState & SCREEN_ON_BIT) != 0) {
// force lights recalculation
int value = (int)mLightSensorValue;
mLightSensorValue = -1;
lightSensorChangedLocked(value);
}
}

//在这里定义了一个receiver接受消息,接受EXTRA_DOCK_STATE

private final class DockReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

//获取EXTRA_DOCK_STATE的状态,并初始化为EXTRA_DOCK_STATE_UNDOCKED状态
int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
Intent.EXTRA_DOCK_STATE_UNDOCKED);
dockStateChanged(state);
}
}

void initInThread() {

.................

filter = new IntentFilter(); //定义一个filter
filter.addAction(Intent.ACTION_DOCK_EVENT); //向filter中添加Intent.ACTION_DOCK_EVENT消息
mContext.registerReceiver(new DockReceiver(), filter);//将filter注册斤receiver中,这样DockReceiver就能接受含有ACTION_DOCK_EVENT的消息了

.........

}

2 : Intent.ACTION_DOCK_EVENT何时发送

在DockObserver.java(frameworks/base/services/java/com/android/server/)中发送

//记住这个函数下面会用到

private final void update() {
mHandler.sendEmptyMessage(MSG_DOCK_STATE);
}

private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_DOCK_STATE:
synchronized (this) {
Slog.i(TAG, "Dock state changed: " + mDockState);

final ContentResolver cr = mContext.getContentResolver();

if (Settings.Secure.getInt(cr,
Settings.Secure.DEVICE_PROVISIONED, 0) == 0) {
Slog.i(TAG, "Device not provisioned, skipping dock broadcast");
return;
}
// Pack up the values and broadcast them to everyone
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);//在这里创建了一个intent,将Intent.EXTRA_DOCK_STATE设置成了mDockState状态,这样上面的reciver就能接受到了
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);

}
}
};
}

mDockState是怎么改变的呢?

//记住这个函数,在后面会讲到他是如何接受驱动发送上来的数据的,他是一个虚函数必须在子类中实现它父类是UEventObserver,

//参数UEventObserver.UEvent event是从父类中传过来的,也就是说父类已经收到了数据,在子类处理而已


public void onUEvent(UEventObserver.UEvent event) {
if (Log.isLoggable(TAG, Log.VERBOSE)) {
Slog.v(TAG, "Dock UEVENT: " + event.toString());
}

synchronized (this) {
try {
int newState = Integer.parseInt(event.get("SWITCH_STATE"));
if (newState != mDockState) {
mPreviousDockState = mDockState;
mDockState = newState;
if (mSystemReady) {
// Don't force screen on when undocking from the desk dock.
// The change in power state will do this anyway.
// FIXME - we should be configurable.
if (mPreviousDockState != Intent.EXTRA_DOCK_STATE_DESK ||
mDockState != Intent.EXTRA_DOCK_STATE_UNDOCKED) {
mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(),
false, true);
}
update();//调用了上面的函数
}
}
} catch (NumberFormatException e) {
Slog.e(TAG, "Could not parse switch state from event " + event);
}
}
}

父类UEventObserver是如何接受数据的?

请看UEventObserver类UEventObserver.java(frameworks/base/core/java/android/os)

//开启了一个线程不断获取数据
public void run() {
native_setup();

byte[] buffer = new byte[1024];
int len;
while (true) {
len = next_event(buffer); //这个函数非常重要,他是jni层的函数,可以直接调用hal层中的函数,获取驱动发上来的uevent数据,在后面会讲到
if (len > 0) {
String bufferStr = new String(buffer, 0, len); // easier to search a String
synchronized (mObservers) {
for (int i = 0; i < mObservers.size(); i += 2) { //在此找到一个属于我们的mObservers
if (bufferStr.indexOf((String)mObservers.get(i)) != -1) {

//在这里向子类调用了onUEvent方法,将onUEvent是虚函数,所有会直接调用到子类中去
((UEventObserver)mObservers.get(i+1)).onUEvent(new UEvent(bufferStr));
}
}
}
}
}
}

我们的mObservers是怎样产生的?

先看查找UEventObserver.java发现mObservers的定义

/** Many to many mapping of string match to observer.
* Multimap would be better, but not available in android, so use
* an ArrayList where even elements are the String match and odd
* elements the corresponding UEventObserver observer */
private ArrayList<Object> mObservers = new ArrayList<Object>();

//发现在子类(DockObserver)的构造函数中调用了startObserving,这样就把我们自己的mObservers加好了

public final synchronized void startObserving(String match) {
ensureThreadStarted();
sThread.addObserver(match, this);
}

private static UEventThread sThread;

public void addObserver(String match, UEventObserver observer) {
synchronized(mObservers) {
mObservers.add(match);
mObservers.add(observer);
}
}

DockObserver的构造函数

public DockObserver(Context context, PowerManagerService pm) {//看到这个参数了吧,在PowerManagerService就会和DockObserver关联了
mContext = context;
mPowerManager = pm;
init(); // set initial status

startObserving(DOCK_UEVENT_MATCH);
}

private static final String DOCK_UEVENT_MATCH = "DEVPATH=/devices/virtual/switch/dock";
private static final String DOCK_STATE_PATH = "/sys/class/switch/dock/state";

更多相关文章

  1. 深入理解Android:卷II
  2. Android(安卓)xml中配置数组资源,在java中调用该数组资源
  3. Android(安卓)MMS/SMS 入口
  4. android 音频管理:AudioPolicyService 和 AudioPolicyManager
  5. Android(安卓)GPUImage
  6. Android打电话的流程
  7. menu.addIntentOptions 添加动态菜单详解
  8. Listview中Button抢占焦点的解决方法
  9. Camera服务之--JNI部分

随机推荐

  1. ArcGIS for Android 100.3.0(1):开发环境配
  2. android设置窗口特性
  3. Android 颜色渲染(五) LinearGradient线
  4. android RN 配置和打包命令
  5. 【Android(安卓)学习系列】 内存泄露(一)
  6. 什么是Dalvik【摘】
  7. layout布局属性、标签属性总结大全
  8. SeekBar 和 RatingBar
  9. Android--用Pull解析器将对象解析成xml文
  10. [Android] 利用Handler实现定时器功能