1. 程式人生 > >Android電源管理系列之PowerManagerService(一)

Android電源管理系列之PowerManagerService(一)

 

PowerManagerService 提供Android系統的電源管理服務,主要功能是控制系統待機狀態,螢幕顯示,亮度調節,光線/距離感測器的控制等。

相關程式碼在以下檔案中

frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/os/PowerManager.java
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp
frameworks/base/core/java/android/os/PowerManagerInternal.java
frameworks/base/services/core/java/com/android/server/power/Notifier.java
device/qcom/common/power/power.c
system/core/libsuspend/autosuspend.c
hardware/libhardware_legacy/power/power.c

初始化流程

跟其他系統服務一樣,PowerManagerService也是繼承於SystemService並通過SystemServer啟動。
SystemServer
frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
  ......
  mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
  ......
}

PowerManagerService
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public final class PowerManagerService extends SystemService
        implements Watchdog.Monitor {
    ......
}

在SystemServer的startBootstrapServices中,通過SystemServiceManager.startService啟動了PowerManagerService,下面首先來看PowerManagerService構造方法。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public PowerManagerService(Context context) {    super(context);    // mContext賦值為SystemContext
    mContext = context;    // 建立訊息處理執行緒並啟動,建立關聯訊息處理執行緒的handler物件
    mHandlerThread = new ServiceThread(TAG,
            Process.THREAD_PRIORITY_DISPLAY, false /*allowIo*/);
    mHandlerThread.start();
    mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
    qcNsrmPowExt = new QCNsrmPowerExtension(this);    synchronized (mLock) {        // 建立"PowerManagerService.WakeLocks"的SuspendBlocker
        mWakeLockSuspendBlocker = createSuspendBlockerLocked("PowerManagerService.WakeLocks");        // 建立"PowerManagerService.Display"的SuspendBlocker
        mDisplaySuspendBlocker = createSuspendBlockerLocked("PowerManagerService.Display");        // 請求DisplaySuspendBlocker,禁止系統進入休眠
        mDisplaySuspendBlocker.acquire();
        mHoldingDisplaySuspendBlocker = true;
        mHalAutoSuspendModeEnabled = false;
        mHalInteractiveModeEnabled = true;        // 設定mWakefulness為喚醒狀態
        mWakefulness = WAKEFULNESS_AWAKE;        // 進入到native層初始化
        nativeInit();
        nativeSetAutoSuspend(false);
        nativeSetInteractive(true);
        nativeSetFeature(POWER_FEATURE_DOUBLE_TAP_TO_WAKE, 0);
    }
}

PowerManagerService建構函式中首先建立了處理訊息的程序及對應的handler物件以進行訊息處理,然後建立SuspendBlocker物件,用於WakeLocks與Display,並設定mWakefulness的初始狀態為WAKEFULNESS_AWAKE,最後進入到native層初始化。下面先看一下關於mWakefulness的定義。

>>> frameworks/base/core/java/android/os/PowerManagerInternal.java/**
 * 裝置處於休眠狀態,只能被wakeUp()喚醒.
 */public static final int WAKEFULNESS_ASLEEP = 0;/**
 * 裝置處於正常工作(fully awake)狀態.
 */public static final int WAKEFULNESS_AWAKE = 1;/**
 * 裝置處於播放屏保狀態.
 */public static final int WAKEFULNESS_DREAMING = 2;/**
 * 裝置處於doze狀態,只有低耗電的屏保可以執行,其他應用被掛起.
 */public static final int WAKEFULNESS_DOZING = 3;

繼續回到PowerManagerService建構函式的native初始化中,首先來看nativeInit的實現。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static const JNINativeMethod gPowerManagerServiceMethods[] = {    /* name, signature, funcPtr */
    { "nativeInit", "()V",
            (void*) nativeInit },
    { "nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
            (void*) nativeAcquireSuspendBlocker },
    { "nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
            (void*) nativeReleaseSuspendBlocker },
    { "nativeSetInteractive", "(Z)V",
            (void*) nativeSetInteractive },
    { "nativeSetAutoSuspend", "(Z)V",
            (void*) nativeSetAutoSuspend },
    { "nativeSendPowerHint", "(II)V",
            (void*) nativeSendPowerHint },
    { "nativeSetFeature", "(II)V",
            (void*) nativeSetFeature },
};

PowerManagerService中的native方法定義如上,nativeInit即呼叫nativeInit()。
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static void nativeInit(JNIEnv* env, jobject obj) {    // 建立一個全域性物件,引用PMS
    gPowerManagerServiceObj = env->NewGlobalRef(obj);    // 利用hw_get_module載入power模組
    status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
            (hw_module_t const**)&gPowerModule);    if (!err) {
        gPowerModule->init(gPowerModule);
    } else {
        ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
    }
}

nativeInit的主要任務時裝載power模組,該模組由廠商實現,以高通為例,如下。
device/qcom/common/power/power.c

tatic struct hw_module_methods_t power_module_methods = {
    .open = NULL,
};struct power_module HAL_MODULE_INFO_SYM = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = POWER_MODULE_API_VERSION_0_2,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = POWER_HARDWARE_MODULE_ID,
        .name = "QCOM Power HAL",
        .author = "Qualcomm",
        .methods = &power_module_methods,
    },

    .init = power_init,
    .powerHint = power_hint,
    .setInteractive = set_interactive,
};

power_module中實現了init,powerHint,setInteractive,nativeInit最終呼叫到HAL power模組的power_init具體實現中。接著看native初始化nativeSetAutoSuspend的實現。

frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {    if (enable) {
        ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_enable() while turning screen off");
        autosuspend_enable();
    } else {
        ALOGD_IF_SLOW(100, "Excessive delay in autosuspend_disable() while turning screen on");
        autosuspend_disable();
    }
}

system/core/libsuspend/autosuspend.c

int autosuspend_disable(void){    int ret;

    ret = autosuspend_init();    if (ret) {        return ret;
    }

    ALOGV("autosuspend_disable\n");    if (!autosuspend_enabled) {        return 0;
    }

    ret = autosuspend_ops->disable();    if (ret) {        return ret;
    }

    autosuspend_enabled = false;    return 0;
}

nativeSetAutoSuspend最終呼叫到libsuspend(參考Android電源管理系列之libsuspend)的autosuspend_disable禁止系統休眠。繼續看native初始化nativeSetInteractive,nativeSetFeature的實現
frameworks/base/services/core/jni/com_android_server_power_PowerManagerService.cpp

static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {    if (gPowerModule) {        if (enable) {
            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
            gPowerModule->setInteractive(gPowerModule, true);
        } else {
            ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
            gPowerModule->setInteractive(gPowerModule, false);
        }
    }
}static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {    int data_param = data;    if (gPowerModule && gPowerModule->setFeature) {
        gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param);
    }
}

同nativeInit一樣,最終都是呼叫到HAL power模組的具體實現中。以上是建構函式的分析流程,下面繼續看PowerManagerService在系統啟動過程中回撥onStart(),onBootPhase(),systemReady()的實現。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void onStart() {
    publishBinderService(Context.POWER_SERVICE, new BinderService());
    publishLocalService(PowerManagerInternal.class, new LocalService());

    Watchdog.getInstance().addMonitor(this);
    Watchdog.getInstance().addThread(mHandler);
}private final class BinderService extends IPowerManager.Stub {
    ......
}private final class LocalService extends PowerManagerInternal {
    ......
}

onStart()中釋出了BinderService,LocalService分別供其他程序,程序內其他服務呼叫,並將PowerManagerService加入到Watchdog監控中。

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void onBootPhase(int phase) {    synchronized (mLock) {        if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
            ......
        } else if (phase == PHASE_BOOT_COMPLETED) {            final long now = SystemClock.uptimeMillis();            // 設定mBootCompleted狀態
            mBootCompleted = true;
            mDirty |= DIRTY_BOOT_COMPLETED;            // 更新userActivity及PowerState,後面分析
            userActivityNoUpdateLocked(
                    now, PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
            updatePowerStateLocked();            // 執行mBootCompletedRunnables中的runnable方法
            if (!ArrayUtils.isEmpty(mBootCompletedRunnables)) {
                Slog.d(TAG, "Posting " + mBootCompletedRunnables.length + " delayed runnables");                for (Runnable r : mBootCompletedRunnables) {
                    BackgroundThread.getHandler().post(r);
                }
            }
            mBootCompletedRunnables = null;
        }
    }
}

onBootPhase中主要設定mBootCompleted狀態,更新PowerState狀態,並執行mBootCompletedRunnables中的runnables方法(低電量模式會設定)。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

public void systemReady(IAppOpsService appOps) {    synchronized (mLock) {
        mSystemReady = true;        // 獲取AppOpsService
        mAppOps = appOps;        // 獲取DreamManager
        mDreamManager = getLocalService(DreamManagerInternal.class);        // 獲取DisplayManagerService
        mDisplayManagerInternal = getLocalService(DisplayManagerInternal.class);
        mPolicy = getLocalService(WindowManagerPolicy.class);        // 獲取mBatteryService
        mBatteryManagerInternal = getLocalService(BatteryManagerInternal.class);

        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);        // 獲取螢幕預設,最大,最小亮度
        mScreenBrightnessSettingMinimum = pm.getMinimumScreenBrightnessSetting();
        mScreenBrightnessSettingMaximum = pm.getMaximumScreenBrightnessSetting();
        mScreenBrightnessSettingDefault = pm.getDefaultScreenBrightnessSetting();        // 獲取SensorManager
        SensorManager sensorManager = new SystemSensorManager(mContext, mHandler.getLooper());

        mBatteryStats = BatteryStatsService.getService();        // 建立Notifier物件,用於廣播power state的變化
        mNotifier = new Notifier(Looper.getMainLooper(), mContext, mBatteryStats,
                mAppOps, createSuspendBlockerLocked("PowerManagerService.Broadcasts"),
                mPolicy);        // 無線充電檢測
        mWirelessChargerDetector = new WirelessChargerDetector(sensorManager,
                createSuspendBlockerLocked("PowerManagerService.WirelessChargerDetector"),
                mHandler);        // 監聽設定的變化
        mSettingsObserver = new SettingsObserver(mHandler);

        mLightsManager = getLocalService(LightsManager.class);
        mAttentionLight = mLightsManager.getLight(LightsManager.LIGHT_ID_ATTENTION);        // Initialize display power management.
        mDisplayManagerInternal.initPowerManagement(
                mDisplayPowerCallbacks, mHandler, sensorManager);        // Register for settings changes.
        final ContentResolver resolver = mContext.getContentResolver();
        resolver.registerContentObserver(Settings.Secure.getUriFor(
                Settings.Secure.SCREENSAVER_ENABLED),
        ......
        IVrManager vrManager =
                (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE);        try {
            vrManager.registerListener(mVrStateCallbacks);
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to register VR mode state listener: " + e);
        }        // 讀取配置
        readConfigurationLocked();
        updateSettingsLocked();
        mDirty |= DIRTY_BATTERY_STATE;
        updatePowerStateLocked();
    }    // Register for broadcasts from other components of the system.
    IntentFilter filter = new IntentFilter();
    filter.addAction(Intent.ACTION_BATTERY_CHANGED);
    filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
    mContext.registerReceiver(new BatteryReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_DREAMING_STARTED);
    filter.addAction(Intent.ACTION_DREAMING_STOPPED);
    mContext.registerReceiver(new DreamReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_USER_SWITCHED);
    mContext.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);

    filter = new IntentFilter();
    filter.addAction(Intent.ACTION_DOCK_EVENT);
    mContext.registerReceiver(new DockReceiver(), filter, null, mHandler);
}

userActivity
userActivity是定義在PowerManager中的SystemApi,使用者向PowerManagerService報告使用者活動,以更新PowerManagerService內部時間/狀態值,推遲系統休眠的時間。下面首先來看userActivity的定義。

frameworks/base/core/java/android/os/PowerManager.java

/**
 * User activity event type: Unspecified event type.
 */public static final int USER_ACTIVITY_EVENT_OTHER = 0;/**
 * User activity event type: Button or key pressed or released.
 */public static final int USER_ACTIVITY_EVENT_BUTTON = 1;/**
 * User activity event type: Touch down, move or up.
 */public static final int USER_ACTIVITY_EVENT_TOUCH = 2;/**
 * User activity event type: Accessibility taking action on behalf of user.
 */public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3;@SystemApipublic void userActivity(long when, int event, int flags) {    try {
        mService.userActivity(when, event, flags);
    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();
    }
}

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private final class BinderService extends IPowerManager.Stub {
  ......  public void userActivity(long eventTime, int event, int flags) {      final long now = SystemClock.uptimeMillis();
      ......      if (eventTime > now) {          throw new IllegalArgumentException("event time must not be in the future");
      }      final int uid = Binder.getCallingUid();      final long ident = Binder.clearCallingIdentity();      try {
          userActivityInternal(eventTime, event, flags, uid);
      } finally {
          Binder.restoreCallingIdentity(ident);
      }
  }
  ......
}

PowerManager中userActivity請求呼叫服務端PowerManagerService BinderService的userActivity,即呼叫內部方法userActivityInternal。

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private void userActivityInternal(long eventTime, int event, int flags, int uid) {    synchronized (mLock) {        if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
            updatePowerStateLocked();
        }
    }
}

userActivityInternal中首先呼叫userActivityNoUpdateLocked更新相關資料及狀態(***NoUpdateLocked僅僅更新內部狀態並不採取任何操作),然後呼叫updatePowerStateLocked更新所有PowerState,下面分析userActivityNoUpdateLocked的實現,updatePowerStateLocked是PowerManagerService的核心方法,在最後進行分析。

frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private boolean userActivityNoUpdateLocked(long eventTime, int event, int flags, int uid) {    // 如果發生時間是上一次休眠或喚醒前,或當前沒有開機完成到systemReady,不採取操作直接返回
    if (eventTime < mLastSleepTime || eventTime < mLastWakeTime
            || !mBootCompleted || !mSystemReady) {        return false;
    }    try {        // 更新mLastInteractivePowerHintTime時間
        if (eventTime > mLastInteractivePowerHintTime) {
            powerHintInternal(POWER_HINT_INTERACTION, 0);
            mLastInteractivePowerHintTime = eventTime;
        }        // 通過mNotifier通知BatteryStats UserActivity事件
        mNotifier.onUserActivity(event, uid);        if (mUserInactiveOverrideFromWindowManager) {
            mUserInactiveOverrideFromWindowManager = false;
            mOverriddenTimeout = -1;
        }        // 如果系統處於休眠狀態,不進行處理
        if (mWakefulness == WAKEFULNESS_ASLEEP
                || mWakefulness == WAKEFULNESS_DOZING
                || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {            return false;
        }        // 根據flag是否在已變暗的情況下是否重啟活動超時更新mLastUserActivityTimeNoChangeLights或mLastUserActivityTime
        // 並且設定mDirty DIRTY_USER_ACTIVITY
        if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {            if (eventTime > mLastUserActivityTimeNoChangeLights
                    && eventTime > mLastUserActivityTime) {
                mLastUserActivityTimeNoChangeLights = eventTime;
                mDirty |= DIRTY_USER_ACTIVITY;                return true;
            }
        } else {            if (eventTime > mLastUserActivityTime) {
                mLastUserActivityTime = eventTime;
                mDirty |= DIRTY_USER_ACTIVITY;                return true;
            }
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_POWER);
    }    return false;
}

gotoSleep
gotoSleep在PowerManager中的定義如下:
frameworks/base/core/java/android/os/PowerManager.java

public void goToSleep(long time) {
    goToSleep(time, GO_TO_SLEEP_REASON_APPLICATION, 0);
}public void goToSleep(long time, int reason, int flags) {    try {
        mService.goToSleep(time, reason, flags);
    } catch (RemoteException e) {        throw e.rethrowFromSystemServer();
    }
}

與userActivity一樣,gotoSleep最終將呼叫到goToSleepInternal。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private final class BinderService extends IPowerManager.Stub {
  ......  public void goToSleep(long eventTime, int reason, int flags) {      if (eventTime > SystemClock.uptimeMillis()) {          throw new IllegalArgumentException("event time must not be in the future");
      }

      mContext.enforceCallingOrSelfPermission(
              android.Manifest.permission.DEVICE_POWER, null);      final int uid = Binder.getCallingUid();      final long ident = Binder.clearCallingIdentity();      try {
          goToSleepInternal(eventTime, reason, flags, uid);
      } finally {
          Binder.restoreCallingIdentity(ident);
      }
  }
  ......
}private void goToSleepInternal(long eventTime, int reason, int flags, int uid) {    synchronized (mLock) {        if (goToSleepNoUpdateLocked(eventTime, reason, flags, uid)) {
            updatePowerStateLocked();
        }
    }
}

goToSleepInternal中將執行goToSleepNoUpdateLocked更新內部狀態,同樣在updatePowerStateLocked中更新PowerState的操作。
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

private boolean goToSleepNoUpdateLocked(long eventTime, int reason, int flags, int uid) {    // 當不處於awake狀態或未開機systemReady,不處理
    if (eventTime < mLastWakeTime
            || mWakefulness == WAKEFULNESS_ASLEEP
            || mWakefulness == WAKEFULNESS_DOZING
            || !mBootCompleted || !mSystemReady) {        return false;
    }    try {
        ......        // 更新mLastSleepTime時間,設定DIRTY_WAKEFULNESS標誌位
        mLastSleepTime = eventTime;
        mSandmanSummoned = true;
        setWakefulnessLocked(WAKEFULNESS_DOZING, reason);        // Report the number of wake locks that will be cleared by going to sleep.
        int numWakeLocksCleared = 0;        final int numWakeLocks = mWakeLocks.size();        for (int i = 0; i < numWakeLocks; i++) {            final WakeLock wakeLock = mWakeLocks.get(i);            switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {                case PowerManager.FULL_WAKE_LOCK:                case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:                case PowerManager.SCREEN_DIM_WAKE_LOCK:
                    numWakeLocksCleared += 1;                    break;
            }
        }        // Skip dozing if requested.
        if ((flags & PowerManager.GO_TO_SLEEP_FLAG_NO_DOZE) != 0) {
            reallyGoToSleepNoUpdateLocked(eventTime, uid);
        }
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_POWER);
    }    return true;
}

goToSleepNoUpdateLocked中更新mLastSleepTime,mWakefulness,mDirty狀態。