Android 4.0 中的PowerManager(電源管理–休眠喚醒)

來源:互聯網
上載者:User

轉寄請註明出處:

http://blog.csdn.net/codectq/article/details/7324879

        最近,在學習讓系統進入休眠的過程中,學習了電源管理的相關知識。為了備忘和理清思路現整理成文,以便日後查閱。

        行動裝置由於自身的限制有一個硬傷就是電量的消耗問題。由於電池的電量有限,所以電源電量的管理顯得就比較重要了。我們可以想象一下,當你去超市買完東西之後,卻發現無法運回家,是多麼難受的一件事情。

        Android的電源管理是在Linux電源管理的基礎之上更好的一個電源管理方案,在這種策略下,通過Android framework層和本地的linux庫,服務和應用都通過“wake lock”來取得CPU,從而達到省電的目的。如果沒有活躍的喚醒鎖,Android將關閉CPU。

         在Android 4.0 中,為上層提供的休眠函數為goToSleep()。下面詳細講解為什麼這個命令會讓系統進去睡眠模式。

        首先,需要明白在Android 系統中一般會有這樣的一個檔案群,XXX.java、XXXservice.java、*XXX*.cpp、*XXX*.c。作為使用者我們首先需要瞭解的就是這個系統能夠為我們提供的服務,如果這些服務會讓我們滿意,我們才會願意為這個服務埋單。因此,在這裡我們就先從服務入手,也就是從PowerManagerService.java開始入手。在這個檔案的line2561出有goToSleep()函數的定義:

 public void goToSleep(long time)

    {

        goToSleepWithReason(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);

    }

        goToSleep()函數接著調用了下面的goToSleepWithReason()函數。函數的定義如下:

public void goToSleepWithReason(long time, int reason)

    {

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);

        synchronized (mLocks) {

            goToSleepLocked(time, reason);

        }

    }

      goToSleepLocked()函數的定義如下:

private void goToSleepLocked(long time, int reason) {

        if (mLastEventTime <= time) {

            mLastEventTime = time;

            // cancel all of the wake locks

            mWakeLockState = SCREEN_OFF;

            int N = mLocks.size();

            int numCleared = 0;

            boolean proxLock = false;

            for (int i=0; i<N; i++) {

                WakeLock wl = mLocks.get(i);

                if (isScreenLock(wl.flags)) {

                    if (((wl.flags & LOCK_MASK) == PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK)

                            && reason == WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR) {

                        proxLock = true;

                    } else {

                        mLocks.get(i).activated = false;

                        numCleared++;

                    }

                }

            }

            if (!proxLock) {

                mProxIgnoredBecauseScreenTurnedOff = true;

                if (mDebugProximitySensor) {

                    Slog.d(TAG, "setting mProxIgnoredBecauseScreenTurnedOff");

                }

            }

            EventLog.writeEvent(EventLogTags.POWER_SLEEP_REQUESTED, numCleared);

            mStillNeedSleepNotification = true;

            mUserState = SCREEN_OFF;

            setPowerState(SCREEN_OFF, false, reason);

            cancelTimerLocked();

        }

    }

        其中,對我們來講最有意義的函數為setPowerState()函數。此函數中調用了 setScreenStateLocked()函數

轉寄請註明出處:

http://blog.csdn.net/codectq/article/details/7324879

private int setScreenStateLocked(boolean on) {

        if (DEBUG_SCREEN_ON) {

            RuntimeException e = new RuntimeException("here");

            e.fillInStackTrace();

            Slog.i(TAG, "Set screen state: " + on, e);

        }

        if (on) {

            if ((mPowerState & SCREEN_ON_BIT) == 0 || mSkippedScreenOn) {

                // If we are turning the screen state on, but the screen

                // light is currently off, then make sure that we set the

轉寄請註明出處:

http://blog.csdn.net/codectq/article/details/7324879

                // light at this point to 0.  This is the case where we are
                // turning on the screen and waiting for the UI to be drawn
                // before showing it to the user.  We want the light off
                // until it is ready to be shown to the user, not it using
                // whatever the last value it had.
                if (DEBUG_SCREEN_ON) {
                    Slog.i(TAG, "Forcing brightness 0: mPowerState=0x"
                            + Integer.toHexString(mPowerState)
                            + " mSkippedScreenOn=" + mSkippedScreenOn);
                }
                mScreenBrightness.forceValueLocked(Power.BRIGHTNESS_OFF);
            }
        }
        int err = Power.setScreenState(on);
        if (err == 0) {
            mLastScreenOnTime = (on ? SystemClock.elapsedRealtime() : 0);
            if (mUseSoftwareAutoBrightness) {
                enableLightSensorLocked(on);

轉寄請註明出處:

http://blog.csdn.net/codectq/article/details/7324879

                if (!on) {
                    // make sure button and key backlights are off too
                    mButtonLight.turnOff();
                    mKeyboardLight.turnOff();
                    // clear current value so we will update based on the new conditions
                    // when the sensor is reenabled.
                    mLightSensorValue = -1;
                    // reset our highest light sensor value when the screen turns off
                    mHighestLightSensorValue = -1;
                }
            }
        }
        return err;
    }

轉寄請註明出處:

http://blog.csdn.net/codectq/article/details/7324879

       此函數調用了Power類中的setScreenState()函數。此函數通過JNI機制,最終到達硬體層的libhardware_legacy/power/Power.c檔案通過對寄存器的操作完成對休眠的操作。在此函數中我們通過傳入的參數是on,來進行相應的處理。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.