资源描述
由Intent.ACTION_DOCK_EVENT(亮度传感器)引发的血案 在调试光感传感器(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 recalculationint value = (int)mLightSensorValue;mLightSensorValue = -1;lightSensorChangedLocked(value);/在这里定义了一个receiver接受消息,接受EXTRA_DOCK_STATEprivate final class DockReceiver extends BroadcastReceiver Overridepublic 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(); /定义一个filterfilter.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() Overridepublic 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 everyoneIntent 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) / Dont 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 byte1024;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 Stringsynchronized (mObservers) for (int i = 0; i mObservers.size(); i += 2) /在此找到一个属于我们的mObserversif (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 mObservers = new ArrayList();/发现在子类(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 statusstartObserving(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;
展开阅读全文