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

Commit c75113a7 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge changes from topic "odpm_api"

* changes:
  Add random noise to power monitor readings
  Add random noise generator for Power Monitor API
  Add feature flag for PowerMonitor API
  Add API SystemHealthManager.getPowerMonitorReadings
parents 1dfbf350 293b4b3a
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ import android.os.IBinder;
import android.os.IDumpstate;
import android.os.IHardwarePropertiesManager;
import android.os.IPowerManager;
import android.os.IPowerStatsService;
import android.os.IRecoverySystem;
import android.os.ISystemUpdateManager;
import android.os.IThermalService;
@@ -1117,8 +1118,10 @@ public final class SystemServiceRegistry {
                new CachedServiceFetcher<SystemHealthManager>() {
            @Override
            public SystemHealthManager createService(ContextImpl ctx) throws ServiceNotFoundException {
                IBinder b = ServiceManager.getServiceOrThrow(BatteryStats.SERVICE_NAME);
                return new SystemHealthManager(IBatteryStats.Stub.asInterface(b));
                IBinder batteryStats = ServiceManager.getServiceOrThrow(BatteryStats.SERVICE_NAME);
                IBinder powerStats = ServiceManager.getServiceOrThrow(Context.POWER_STATS_SERVICE);
                return new SystemHealthManager(IBatteryStats.Stub.asInterface(batteryStats),
                        IPowerStatsService.Stub.asInterface(powerStats));
            }});

        registerService(Context.CONTEXTHUB_SERVICE, ContextHubManager.class,
+39 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.os;

import android.os.ResultReceiver;

/** @hide */
interface IPowerStatsService {
    /** @hide */
    const String KEY_MONITORS = "monitors";
    /** @hide */
    const String KEY_ENERGY = "energy";
    /** @hide */
    const String KEY_TIMESTAMPS = "timestamps";

    /** @hide */
    const int RESULT_SUCCESS = 0;
    /** @hide */
    const int RESULT_UNSUPPORTED_POWER_MONITOR = 1;

    /** {@hide} */
    oneway void getSupportedPowerMonitors(in ResultReceiver resultReceiver);
    /** {@hide} */
    oneway void getPowerMonitorReadings(in int[] powerMonitorIndices,
            in ResultReceiver resultReceiver);
}
+20 −0
Original line number Diff line number Diff line
/*
 * Copyright 2023, 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.os;

/** @hide */
@JavaOnlyStableParcelable parcelable PowerMonitor;
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.os;

import android.annotation.IntDef;
import android.annotation.NonNull;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * @hide
 */
public final class PowerMonitor implements Parcelable {

    /**
     * Power monitor corresponding to a subsystem. The energy value may be a direct pass-through
     * power rail measurement, or modeled in some fashion.  For example, an energy consumer may
     * represent a combination of multiple rails or a portion of a rail shared between subsystems,
     * e.g. WiFi and Bluetooth are often handled by the same chip, powered by a shared rail.
     * Some consumer names are standardized (see android.hardware.power.stats.EnergyConsumerType),
     * others are not.
     */
    public static final int POWER_MONITOR_TYPE_CONSUMER = 0;

    /**
     * Power monitor corresponding to a directly measured power rail. Rails are device-specific:
     * no assumptions can be made about the source of those measurements across different devices,
     * even if they have the same name.
     */
    public static final int POWER_MONITOR_TYPE_MEASUREMENT = 1;

    /** @hide */
    @IntDef(flag = true, prefix = {"POWER_MONITOR_TYPE_"}, value = {
            POWER_MONITOR_TYPE_CONSUMER,
            POWER_MONITOR_TYPE_MEASUREMENT
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PowerMonitorType {
    }

    /**
     * These indices are not guaranteed to be stable across reboots and should not
     * be persisted.
     *
     * @hide
     */
    public final int index;
    @PowerMonitorType
    public final int type;
    @NonNull
    public final String name;

    /**
     * @hide
     */
    public PowerMonitor(int index, int type, @NonNull String name) {
        this.index = index;
        this.type = type;
        this.name = name;
    }

    private PowerMonitor(Parcel in) {
        index = in.readInt();
        type = in.readInt();
        name = in.readString();
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(index);
        dest.writeInt(type);
        dest.writeString(name);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<PowerMonitor> CREATOR = new Creator<>() {
        @Override
        public PowerMonitor createFromParcel(@NonNull Parcel in) {
            return new PowerMonitor(in);
        }

        @Override
        public PowerMonitor[] newArray(int size) {
            return new PowerMonitor[size];
        }
    };
}
+92 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.os;

import android.annotation.NonNull;

import java.util.Arrays;
import java.util.Comparator;

/**
 * A collection of energy measurements from Power Monitors.
 *
 * @hide
 */
public final class PowerMonitorReadings {
    public static final int ENERGY_UNAVAILABLE = -1;

    @NonNull
    private final PowerMonitor[] mPowerMonitors;
    @NonNull
    private final long[] mEnergyUws;
    @NonNull
    private final long[] mTimestampsMs;

    private static final Comparator<PowerMonitor> POWER_MONITOR_COMPARATOR =
            Comparator.comparingInt(pm -> pm.index);

    /**
     * @param powerMonitors array of power monitor (ODPM) rails, sorted by PowerMonitor.index
     * @hide
     */
    public PowerMonitorReadings(PowerMonitor[] powerMonitors,
            long[] energyUws, long[] timestampsMs) {
        mPowerMonitors = powerMonitors;
        mEnergyUws = energyUws;
        mTimestampsMs = timestampsMs;
    }

    /**
     * Returns energy consumed by the specified power monitor since boot in microwatt-seconds.
     * Does not persist across reboots.
     * Represents total energy: both on-battery and plugged-in.
     */
    public long getConsumedEnergyUws(PowerMonitor powerMonitor) {
        int offset = Arrays.binarySearch(mPowerMonitors, powerMonitor, POWER_MONITOR_COMPARATOR);
        if (offset >= 0) {
            return mEnergyUws[offset];
        }
        return ENERGY_UNAVAILABLE;
    }

    /**
     * Elapsed realtime when the snapshot was taken.
     */
    public long getTimestampMs(PowerMonitor powerMonitor) {
        int offset = Arrays.binarySearch(mPowerMonitors, powerMonitor, POWER_MONITOR_COMPARATOR);
        if (offset >= 0) {
            return mTimestampsMs[offset];
        }
        return 0;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(" monitors: [");
        for (int i = 0; i < mPowerMonitors.length; i++) {
            if (i != 0) {
                sb.append(", ");
            }
            sb.append(mPowerMonitors[i].name)
                    .append(" = ").append(mEnergyUws[i])
                    .append(" (").append(mTimestampsMs[i]).append(')');
        }
        sb.append("]");
        return sb.toString();
    }
}
Loading