Android11 关机充电动画在99%显示充满ui

问题:基于Android11关机动画,当关机动画显示为充满状态时,开机进入后发现状态栏或settings中电池的电量却为99%?
分析:这个问题和电池状态驱动节点有关系,电池的充电状态节点是*/*/status,status有1 2 3 4 5 五种状态值,当status==5即为FUll充满状态。部分项目status节点在当电量为99%时status即为full,造成了关机动画展示问题。

hardware/interfaces/health/1.0/type.hal

@export(name="", value_prefix="BATTERY_STATUS_")
enum BatteryStatus : int32_t {
    UNKNOWN = 1,
    CHARGING = 2,
    DISCHARGING = 3,
    /**
     * Battery is *not* charging - special case when charger is present
     * but battery isn't charging
     */
    NOT_CHARGING = 4,
    FULL = 5,
};

流程:关机动画电池节点status判断逻辑

system/core/healthd/healthd_mode_charger.cpp  UpdateScreenState方法:

system/core/healthd/healthd_draw.cpp  redraw_screen->draw_battery->draw_percent方法:

void Charger::UpdateScreenState(int64_t now) {
    int disp_time;

    if (!batt_anim_.run || now < next_screen_transition_) return;

    // If battery level is not ready, keep checking in the defined time
    if (health_info_.batteryLevel == 0 && health_info_.batteryStatus == BatteryStatus::UNKNOWN) {
        if (wait_batt_level_timestamp_ == 0) {
            // Set max delay time and skip drawing screen
            wait_batt_level_timestamp_ = now + MAX_BATT_LEVEL_WAIT_TIME;
            LOGV("[%" PRId64 "] wait for battery capacity ready\n", now);
            return;
        } else if (now <= wait_batt_level_timestamp_) {
            // Do nothing, keep waiting
            return;
        }
        // If timeout and battery level is still not ready, draw unknown battery
    }

    if (healthd_draw_ == nullptr) {
        std::optional<bool> out_screen_on;
        service()->shouldKeepScreenOn([&](Result res, bool screen_on) {
            if (res == Result::SUCCESS) {
                *out_screen_on = screen_on;
            }
        });
        if (out_screen_on.has_value()) {
            if (!*out_screen_on) {
                LOGV("[%" PRId64 "] leave screen off\n", now);
                batt_anim_.run = false;
                next_screen_transition_ = -1;
                if (charger_online()) request_suspend(true);
                return;
            }
        }

        healthd_draw_.reset(new HealthdDraw(&batt_anim_));

        if (android::sysprop::ChargerProperties::disable_init_blank().value_or(false)) {
            healthd_draw_->blank_screen(true);
            screen_blanked_ = true;
        }
    }

    /* animation is over, blank screen and leave */
    if (batt_anim_.num_cycles > 0 && batt_anim_.cur_cycle == batt_anim_.num_cycles) {
        reset_animation(&batt_anim_);
        next_screen_transition_ = -1;
        healthd_draw_->blank_screen(true);
        screen_blanked_ = true;
        LOGV("[%" PRId64 "] animation done\n", now);
        if (charger_online()) request_suspend(true);
        return;
    }

    disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time;

    /* unblank the screen on first cycle and first frame */
    if (batt_anim_.cur_cycle == 0 && batt_anim_.cur_frame == 0) healthd_draw_->blank_screen(false);

    if (screen_blanked_) {
        healthd_draw_->blank_screen(false);
        screen_blanked_ = false;
    }

    /* animation starting, set up the animation */
    if (batt_anim_.cur_frame == 0) {
        LOGV("[%" PRId64 "] animation starting\n", now);
        batt_anim_.cur_level = health_info_.batteryLevel;
        batt_anim_.cur_status = (int)health_info_.batteryStatus;
        if (health_info_.batteryLevel >= 0 && batt_anim_.num_frames != 0) {
            /* find first frame given current battery level */
            for (int i = 0; i < batt_anim_.num_frames; i++) {
                if (batt_anim_.cur_level >= batt_anim_.frames[i].min_level &&
                    batt_anim_.cur_level <= batt_anim_.frames[i].max_level) {
                    batt_anim_.cur_frame = i;
                    break;
                }
            }

            if (charger_online()) {
                // repeat the first frame first_frame_repeats times
                disp_time = batt_anim_.frames[batt_anim_.cur_frame].disp_time *
                            batt_anim_.first_frame_repeats;
            } else {
                disp_time = UNPLUGGED_DISPLAY_TIME / batt_anim_.num_cycles;
            }

            LOGV("cur_frame=%d disp_time=%d\n", batt_anim_.cur_frame, disp_time);
        }
    }

   //********代码位置*************
    /* draw the new frame (@ cur_frame) */
    healthd_draw_->redraw_screen(&batt_anim_, surf_unknown_);

    /* if we don't have anim frames, we only have one image, so just bump
     * the cycle counter and exit
     */
    if (batt_anim_.num_frames == 0 || batt_anim_.cur_level < 0) {
        LOGW("[%" PRId64 "] animation missing or unknown battery status\n", now);
        next_screen_transition_ = now + BATTERY_UNKNOWN_TIME;
        batt_anim_.cur_cycle++;
        return;
    }

    /* schedule next screen transition */
    next_screen_transition_ = curr_time_ms() + disp_time;

    /* advance frame cntr to the next valid frame only if we are charging
     * if necessary, advance cycle cntr, and reset frame cntr
     */
    if (charger_online()) {
        batt_anim_.cur_frame++;

        while (batt_anim_.cur_frame < batt_anim_.num_frames &&
               (batt_anim_.cur_level < batt_anim_.frames[batt_anim_.cur_frame].min_level ||
                batt_anim_.cur_level > batt_anim_.frames[batt_anim_.cur_frame].max_level)) {
            batt_anim_.cur_frame++;
        }
        if (batt_anim_.cur_frame >= batt_anim_.num_frames) {
            batt_anim_.cur_cycle++;
            batt_anim_.cur_frame = 0;

            /* don't reset the cycle counter, since we use that as a signal
             * in a test above to check if animation is over
             */
        }
    } else {
        /* Stop animating if we're not charging.
         * If we stop it immediately instead of going through this loop, then
         * the animation would stop somewhere in the middle.
         */
        batt_anim_.cur_frame = 0;
        batt_anim_.cur_cycle++;
    }
}
void HealthdDraw::draw_percent(const animation* anim) {
    if (!graphics_available) return;
    int cur_level = anim->cur_level;
    //***代码修改处,添加level==100,当电量100才展示充满电ui***
    if (anim->cur_status == BATTERY_STATUS_FULL && cur_level==100) {
        cur_level = 100;
    }

    if (cur_level < 0) return;

    const animation::text_field& field = anim->text_percent;
    if (field.font == nullptr || field.font->char_width == 0 || field.font->char_height == 0) {
        return;
    }

    std::string str = base::StringPrintf("%d%%", cur_level);

    int x, y;
    determine_xy(field, str.size(), &x, &y);

    LOGV("drawing percent %s %d %d\n", str.c_str(), x, y);
    gr_color(field.color_r, field.color_g, field.color_b, field.color_a);
    draw_text(field.font, x, y, str.c_str());
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值