在调试光感传感器(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";