lighting sensor 部分分析

来源:互联网 发布:优秀的淘宝店铺设计 编辑:程序博客网 时间:2024/06/05 10:32

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