Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fc72a8d1 authored by Kumar Anand's avatar Kumar Anand Committed by Ahmed ElArabawy
Browse files

power hal: Add power HAL API 1.1



Extend APIs to collect subsystem low power statistics.

Many subsystems (e.g.wifi) could be living on an
independent power island (sourced from VBatt directly)
and might even have their own dedicated XTAL to source
their clocks. Since these SOCs are capable of
autonomously operating (while the platform is in one
of the sleep states), they are still drawing power
from the VBatt. Hence it is critical to understand
the  (SOC) level low power statistics as well when
the battery level changes and be able to find any
correlation in event of unexpected battery drain.

Bug: 29339696
Test: VTS
Change-Id: I1b6ea557dbdf1aa06e9560635fcba8d54afabda7
Signed-off-by: default avatarAhmed ElArabawy <arabawy@google.com>
parent a677e932
Loading
Loading
Loading
Loading

power/1.1/Android.bp

0 → 100644
+56 −0
Original line number Diff line number Diff line
// This file is autogenerated by hidl-gen. Do not edit manually.

genrule {
    name: "android.hardware.power@1.1_genc++",
    tools: ["hidl-gen"],
    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.1",
    srcs: [
        "types.hal",
        "IPower.hal",
    ],
    out: [
        "android/hardware/power/1.1/types.cpp",
        "android/hardware/power/1.1/PowerAll.cpp",
    ],
}

genrule {
    name: "android.hardware.power@1.1_genc++_headers",
    tools: ["hidl-gen"],
    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.power@1.1",
    srcs: [
        "types.hal",
        "IPower.hal",
    ],
    out: [
        "android/hardware/power/1.1/types.h",
        "android/hardware/power/1.1/IPower.h",
        "android/hardware/power/1.1/IHwPower.h",
        "android/hardware/power/1.1/BnHwPower.h",
        "android/hardware/power/1.1/BpHwPower.h",
        "android/hardware/power/1.1/BsPower.h",
    ],
}

cc_library_shared {
    name: "android.hardware.power@1.1",
    generated_sources: ["android.hardware.power@1.1_genc++"],
    generated_headers: ["android.hardware.power@1.1_genc++_headers"],
    export_generated_headers: ["android.hardware.power@1.1_genc++_headers"],
    shared_libs: [
        "libhidlbase",
        "libhidltransport",
        "libhwbinder",
        "liblog",
        "libutils",
        "libcutils",
        "android.hardware.power@1.0",
    ],
    export_shared_lib_headers: [
        "libhidlbase",
        "libhidltransport",
        "libhwbinder",
        "libutils",
        "android.hardware.power@1.0",
    ],
}

power/1.1/Android.mk

0 → 100644
+158 −0
Original line number Diff line number Diff line
# This file is autogenerated by hidl-gen. Do not edit manually.

LOCAL_PATH := $(call my-dir)

################################################################################

include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.power-V1.1-java
LOCAL_MODULE_CLASS := JAVA_LIBRARIES

intermediates := $(local-generated-sources-dir)

HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)

LOCAL_JAVA_LIBRARIES := \
    android.hardware.power-V1.0-java \
    android.hidl.base-V1.0-java \


#
# Build types.hal (PowerStateSubsystem)
#
GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystem.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::types.PowerStateSubsystem

$(GEN): $(LOCAL_PATH)/types.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)

#
# Build types.hal (PowerStateSubsystemSleepState)
#
GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystemSleepState.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::types.PowerStateSubsystemSleepState

$(GEN): $(LOCAL_PATH)/types.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)

#
# Build IPower.hal
#
GEN := $(intermediates)/android/hardware/power/V1_1/IPower.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IPower.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
$(GEN): $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::IPower

$(GEN): $(LOCAL_PATH)/IPower.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_JAVA_LIBRARY)


################################################################################

include $(CLEAR_VARS)
LOCAL_MODULE := android.hardware.power-V1.1-java-static
LOCAL_MODULE_CLASS := JAVA_LIBRARIES

intermediates := $(local-generated-sources-dir)

HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)

LOCAL_STATIC_JAVA_LIBRARIES := \
    android.hardware.power-V1.0-java-static \
    android.hidl.base-V1.0-java-static \


#
# Build types.hal (PowerStateSubsystem)
#
GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystem.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::types.PowerStateSubsystem

$(GEN): $(LOCAL_PATH)/types.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)

#
# Build types.hal (PowerStateSubsystemSleepState)
#
GEN := $(intermediates)/android/hardware/power/V1_1/PowerStateSubsystemSleepState.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::types.PowerStateSubsystemSleepState

$(GEN): $(LOCAL_PATH)/types.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)

#
# Build IPower.hal
#
GEN := $(intermediates)/android/hardware/power/V1_1/IPower.java
$(GEN): $(HIDL)
$(GEN): PRIVATE_HIDL := $(HIDL)
$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/IPower.hal
$(GEN): PRIVATE_DEPS += $(LOCAL_PATH)/types.hal
$(GEN): $(LOCAL_PATH)/types.hal
$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
$(GEN): PRIVATE_CUSTOM_TOOL = \
        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
        -Ljava \
        -randroid.hardware:hardware/interfaces \
        -randroid.hidl:system/libhidl/transport \
        android.hardware.power@1.1::IPower

$(GEN): $(LOCAL_PATH)/IPower.hal
	$(transform-generated-source)
LOCAL_GENERATED_SOURCES += $(GEN)
include $(BUILD_STATIC_JAVA_LIBRARY)



include $(call all-makefiles-under,$(LOCAL_PATH))

power/1.1/IPower.hal

0 → 100644
+36 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package android.hardware.power@1.1;

import android.hardware.power@1.0;

/**
 * Interface to collect subsystem level sleep information
 */
interface IPower extends android.hardware.power@1.0::IPower {

    /**
     * Subsystem-level sleep state stats:
     * Report cumulative info on the statistics on subsystem-level sleep states
     * since boot.
     *
     * @return subsystems supported on this device and their sleep states
     * @return retval SUCCESS on success or FILESYSTEM_ERROR on filesystem
     * nodes access error.
     */
    getSubsystemLowPowerStats()
            generates (vec<PowerStateSubsystem> subsystems, Status retval);
};
+32 −0
Original line number Diff line number Diff line
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

cc_binary {
    proprietary: true,
    defaults: ["hidl_defaults"],
    relative_install_path: "hw",
    name: "android.hardware.power@1.1-service",
    init_rc: ["android.hardware.power@1.1-service.rc"],
    srcs: ["service.cpp" , "Power.cpp"],

    shared_libs: [
        "liblog",
        "libdl",
        "libutils",
        "libhardware",
        "libhidlbase",
        "libhidltransport",
        "android.hardware.power@1.1",
    ],
}
+172 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "android.hardware.power@1.1-impl"

#include <log/log.h>

#include <hardware/hardware.h>
#include <hardware/power.h>

#include "Power.h"

namespace android {
namespace hardware {
namespace power {
namespace V1_1 {
namespace implementation {

using ::android::hardware::power::V1_0::Feature;
using ::android::hardware::power::V1_0::PowerHint;
using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
using ::android::hardware::power::V1_0::Status;
using ::android::hardware::power::V1_1::PowerStateSubsystem;
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;

Power::Power(power_module_t *module) : mModule(module) {
    if (mModule)
        mModule->init(mModule);
}

Power::~Power() {
    delete(mModule);
}

// Methods from ::android::hardware::power::V1_0::IPower follow.
Return<void> Power::setInteractive(bool interactive)  {
    if (mModule->setInteractive)
        mModule->setInteractive(mModule, interactive ? 1 : 0);
    return Void();
}

Return<void> Power::powerHint(PowerHint hint, int32_t data)  {
    int32_t param = data;
    if (mModule->powerHint) {
        if (data)
            mModule->powerHint(mModule, static_cast<power_hint_t>(hint), &param);
        else
            mModule->powerHint(mModule, static_cast<power_hint_t>(hint), NULL);
    }
    return Void();
}

Return<void> Power::setFeature(Feature feature, bool activate)  {
    if (mModule->setFeature)
        mModule->setFeature(mModule, static_cast<feature_t>(feature),
                activate ? 1 : 0);
    return Void();
}

Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb)  {
    hidl_vec<PowerStatePlatformSleepState> states;
    ssize_t number_platform_modes;
    size_t *voters = nullptr;
    power_state_platform_sleep_state_t *legacy_states = nullptr;
    int ret;

    if (mModule->get_number_of_platform_modes == nullptr ||
            mModule->get_voter_list == nullptr ||
            mModule->get_platform_low_power_stats == nullptr)
    {
        _hidl_cb(states, Status::SUCCESS);
        return Void();
    }

    number_platform_modes = mModule->get_number_of_platform_modes(mModule);
    if (number_platform_modes)
    {
       if ((ssize_t) (SIZE_MAX / sizeof(size_t)) <= number_platform_modes)  // overflow
           goto done;
       voters = new (std::nothrow) size_t [number_platform_modes];
       if (voters == nullptr)
           goto done;

       ret = mModule->get_voter_list(mModule, voters);
       if (ret != 0)
           goto done;

       if ((ssize_t) (SIZE_MAX / sizeof(power_state_platform_sleep_state_t))
           <= number_platform_modes)  // overflow
           goto done;
       legacy_states = new (std::nothrow)
           power_state_platform_sleep_state_t [number_platform_modes];
       if (legacy_states == nullptr)
           goto done;

       for (int i = 0; i < number_platform_modes; i++)
       {
          legacy_states[i].voters = nullptr;
          legacy_states[i].voters = new power_state_voter_t [voters[i]];
          if (legacy_states[i].voters == nullptr)
              goto done;
       }

       ret = mModule->get_platform_low_power_stats(mModule, legacy_states);
       if (ret != 0)
           goto done;

       states.resize(number_platform_modes);
       for (int i = 0; i < number_platform_modes; i++)
       {
          power_state_platform_sleep_state_t& legacy_state = legacy_states[i];
          PowerStatePlatformSleepState& state = states[i];
          state.name = legacy_state.name;
          state.residencyInMsecSinceBoot = legacy_state.residency_in_msec_since_boot;
          state.totalTransitions = legacy_state.total_transitions;
          state.supportedOnlyInSuspend = legacy_state.supported_only_in_suspend;
          state.voters.resize(voters[i]);
          for(size_t j = 0; j < voters[i]; j++)
          {
              state.voters[j].name = legacy_state.voters[j].name;
              state.voters[j].totalTimeInMsecVotedForSinceBoot = legacy_state.voters[j].total_time_in_msec_voted_for_since_boot;
              state.voters[j].totalNumberOfTimesVotedSinceBoot = legacy_state.voters[j].total_number_of_times_voted_since_boot;
          }
       }
    }
done:
    if (legacy_states)
    {
        for (int i = 0; i < number_platform_modes; i++)
        {
            if(legacy_states[i].voters)
                delete(legacy_states[i].voters);
        }
    }
    delete[] legacy_states;
    delete[] voters;
    _hidl_cb(states, Status::SUCCESS);
    return Void();
}

// Methods from ::android::hardware::power::V1_1::IPower follow.
Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
    hidl_vec<PowerStateSubsystem> subsystems;
    ssize_t number_subsystems = 0;

    //This API will report zero subsystems to support older devices
    //For devices that support this API, they will have their own implementation
    subsystems.resize(number_subsystems);
    _hidl_cb(subsystems, Status::SUCCESS);
    return Void();
}

} // namespace implementation
}  // namespace V1_1
}  // namespace power
}  // namespace hardware
}  // namespace android
Loading