安卓下电源管理一

CarPowermanagerService是如何收到电源状态变化的?

PowerHalService

PowerHalService是如何从VHal上获取电源状态变化?

PowerHalService在初始化时就通过配置好的Hashmap来订阅各种电源相关的属性

@Override
    public void init() {
        synchronized (mLock) {
            for (HalPropConfig config : mProperties.values()) {
                if (VehicleHal.isPropertySubscribable(config)) {
                    mHal.subscribeProperty(this, config.getPropId());
                }
            }
            HalPropConfig brightnessProperty = mProperties.get(DISPLAY_BRIGHTNESS);
            if (brightnessProperty != null) {
                HalAreaConfig[] areaConfigs = brightnessProperty.getAreaConfigs();
                mMaxDisplayBrightness = areaConfigs.length > 0
                        ? areaConfigs[0].getMaxInt32Value() : 0;
                if (mMaxDisplayBrightness <= 0) {
                    Slogf.w(CarLog.TAG_POWER, "Max display brightness from vehicle HAL is invalid:"
                            + mMaxDisplayBrightness);
                    mMaxDisplayBrightness = 1;
                }
            }
        }
    }

当VHal会在这些属性发生变化的时候,就会通知到PowerHalService中。

PowerHalService的处理

@Override
    public void onHalEvents(List<HalPropValue> values) {
        PowerEventListener listener;
        synchronized (mLock) {
            if (mListener == null) {
                if (mQueuedEvents == null) {
                    mQueuedEvents = new LinkedList<>();
                }
                mQueuedEvents.addAll(values);
                return;
            }
            listener = mListener;
        }
        dispatchEvents(values, listener);
    }

这个函数用来让Vhal将所有的变化事件写入到mQueueEvents中

事件的处理

private void dispatchEvents(List<HalPropValue> values, PowerEventListener listener) {
        for (HalPropValue v : values) {
            switch (v.getPropId()) {
                case AP_POWER_STATE_REPORT:
                    // Ignore this property event. It was generated inside of CarService.
                    break;
                case AP_POWER_STATE_REQ:
                    int state;
                    int param;
                    try {
                        state = v.getInt32Value(VehicleApPowerStateReqIndex.STATE);
                        param = v.getInt32Value(VehicleApPowerStateReqIndex.ADDITIONAL);
                    } catch (IndexOutOfBoundsException e) {
                        Slogf.e(CarLog.TAG_POWER, "Received invalid event, ignore, int32Values: "
                                + v.dumpInt32Values(), e);
                        break;
                    }
                    Slogf.i(CarLog.TAG_POWER, "Received AP_POWER_STATE_REQ="
                            + powerStateReqName(state) + " param=" + param);
                    listener.onApPowerStateChange(new PowerState(state, param));
                    break;
                case DISPLAY_BRIGHTNESS:
                {
                    int maxBrightness;
                    synchronized (mLock) {
                        maxBrightness = mMaxDisplayBrightness;
                    }
                    int brightness;
                    try {
                        brightness = v.getInt32Value(0) * MAX_BRIGHTNESS / maxBrightness;
                    } catch (IndexOutOfBoundsException e) {
                        Slogf.e(CarLog.TAG_POWER, "Received invalid event, ignore, int32Values: "
                                + v.dumpInt32Values(), e);
                        break;
                    }
                    if (brightness < 0) {
                        Slogf.e(CarLog.TAG_POWER, "invalid brightness: " + brightness
                                + ", set to 0");
                        brightness = 0;
                    } else if (brightness > MAX_BRIGHTNESS) {
                        Slogf.e(CarLog.TAG_POWER, "invalid brightness: " + brightness + ", set to "
                                + MAX_BRIGHTNESS);
                        brightness = MAX_BRIGHTNESS;
                    }
                    Slogf.i(CarLog.TAG_POWER, "Received DISPLAY_BRIGHTNESS=" + brightness);
                    listener.onDisplayBrightnessChange(brightness);
                    break;
                }
            }
        }
    }

此方法用来处理具体的事件,从代码可以看到在PowerHalService中主要处理的是三类事件

  1. AP_POWER_STATE_REPORT

  2. AP_POWER_STATE_REQ

  3. DISPLAY_BRIGHTNESS

AP_POWER_STATE_REQ 事件需要使用订阅者的onApPowerStateChange来进行处理。

CarPowerManagementService

OnApPowerStateChange

    @Override
    public void onApPowerStateChange(PowerState state) {
        EventLogHelper.writeCarPowerManagerStateRequest(state.mState, state.mParam);
        synchronized (mLock) {
            mPendingPowerStates.addFirst(new CpmsState(state));
            mLock.notify();
        }
        mHandler.handlePowerStateChange();
    }

所有的属性改变的事件都会被放入到mPendingPowerStates这个list中,然后等待doHandlePowerStateChange来处理。

    private void doHandlePowerStateChange() {
        CpmsState state;
        synchronized (mLock) {
            state = mPendingPowerStates.pollFirst();
            if (state == null) {
                Slogf.w(TAG, "No more power state to process");
                return;
            }
            Slogf.i(TAG, "doHandlePowerStateChange: newState=%s", state.name());
            if (!needPowerStateChangeLocked(state)) {
                // We may need to process the pending power state request.
                if (!mPendingPowerStates.isEmpty()) {
                    Slogf.i(TAG, "There is a pending power state change request. requesting the "
                            + "processing...");
                    mHandler.handlePowerStateChange();
                }
                return;
            }
            // now real power change happens. Whatever was queued before should be all cancelled.
            mPendingPowerStates.clear();
            cancelWaitingForCompletion();
            mCurrentState = state;
        }
        mHandler.cancelProcessingComplete();

        Slogf.i(TAG, "setCurrentState %s", state);
        CarStatsLogHelper.logPowerState(state.mState);
        EventLogHelper.writeCarPowerManagerStateChange(state.mState);
        switch (state.mState) {
            case CpmsState.WAIT_FOR_VHAL:
                handleWaitForVhal(state);
                break;
            case CpmsState.ON:
                handleOn();
                break;
            case CpmsState.SHUTDOWN_PREPARE:
                handleShutdownPrepare(state);
                break;
            case CpmsState.SIMULATE_SLEEP:
            case CpmsState.SIMULATE_HIBERNATION:
                simulateShutdownPrepare(state);
                break;
            case CpmsState.WAIT_FOR_FINISH:
                handleWaitForFinish(state);
                break;
            case CpmsState.SUSPEND:
                // Received FINISH from VHAL
                handleFinish();
                break;
            default:
                // Illegal state
                // TODO(b/202414427): Add handling of illegal state
                break;
        }
    }

HandleFinish最终会调用linux kernel 底层进入STR流程

private void handleFinish() {
        int listenerState;
        synchronized (mLock) {
            switch (mActionOnFinish) {
                case ACTION_ON_FINISH_SHUTDOWN:
                    listenerState = CarPowerManager.STATE_POST_SHUTDOWN_ENTER;
                    break;
                case ACTION_ON_FINISH_DEEP_SLEEP:
                    listenerState = CarPowerManager.STATE_POST_SUSPEND_ENTER;
                    break;
                case ACTION_ON_FINISH_HIBERNATION:
                    listenerState = CarPowerManager.STATE_POST_HIBERNATION_ENTER;
                    break;
                default:
                    Slogf.w(TAG, "Invalid action on finish: %d", mActionOnFinish);
                    return;
            }
        }
        int timeoutMs = getPostShutdownEnterTimeoutConfig();
        sendPowerManagerEvent(listenerState, timeoutMs);
        Runnable taskAtCompletion = () -> {
            Slogf.i(TAG, "All listeners completed for %s", powerStateToString(listenerState));
            doHandleFinish();
        };
        Slogf.i(TAG, "Start waiting for listener completion for %s",
                powerStateToString(listenerState));
        waitForCompletion(taskAtCompletion, /* taskAtInterval= */ null, timeoutMs,
                /* intervalMs= */ -1);
    }
  1. 确定监听器状态

    • 根据 mActionOnFinish 的值,确定监听器状态 listenerState。

    • ACTION_ON_FINISH_SHUTDOWN 对应 CarPowerManager.STATE_POST_SHUTDOWN_ENTER。

    • ACTION_ON_FINISH_DEEP_SLEEP 对应 CarPowerManager.STATE_POST_SUSPEND_ENTER。

    • ACTION_ON_FINISH_HIBERNATION 对应 CarPowerManager.STATE_POST_HIBERNATION_ENTER。

    • 如果 mActionOnFinish 的值无效,记录警告日志并返回。

  2. 发送电源管理事件

    • 调用 sendPowerManagerEvent 方法,发送电源管理事件,通知监听器当前的电源状态。

    • sendPowerManagerEvent 方法会通知所有注册的监听器当前的电源状态,并设置超时时间。

  3. 等待监听器完成

    • 创建一个 Runnable 对象 taskAtCompletion,在所有监听器完成后执行。

    • 记录日志,表示开始等待监听器完成。

    • 调用 waitForCompletion 方法,等待所有监听器完成。

private void doHandleFinish() {
        boolean simulatedMode;
        synchronized (mSimulationWaitObject) {
            simulatedMode = mInSimulatedDeepSleepMode;
        }
        boolean mustShutDown;
        boolean forceReboot;
        synchronized (mLock) {
            mustShutDown = (mActionOnFinish == ACTION_ON_FINISH_SHUTDOWN) && !simulatedMode;
            forceReboot = mRebootAfterGarageMode;
            mRebootAfterGarageMode = false;
        }
        if (forceReboot) {
            PowerManager powerManager = mContext.getSystemService(PowerManager.class);
            if (powerManager == null) {
                Slogf.wtf(TAG, "No PowerManager. Cannot reboot.");
            } else {
                Slogf.i(TAG, "GarageMode has completed. Forcing reboot.");
                powerManager.reboot("GarageModeReboot");
                throw new AssertionError("Should not return from PowerManager.reboot()");
            }
        }
        // To make Kernel implementation simpler when going into sleep.
        if (mWifiAdjustmentForSuspend) disableWifi();

        if (mustShutDown) {
            // shutdown HU
            mSystemInterface.shutdown();
        } else {
            doHandleDeepSleep(simulatedMode);
        }
        synchronized (mLock) {
            mShutdownOnNextSuspend = false;
        }
    }

休眠流程图

对应到Android的官网流程中关于deepsleep的时序图如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值