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

Commit 4d815d93 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add wakeup alarm anomaly detector"

parents ec5e28ae 495de548
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ import android.util.Log;
import android.util.SparseLongArray;

import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.internal.util.ArrayUtils;
import com.android.settings.overlay.FeatureFactory;

import java.lang.annotation.Retention;
@@ -213,6 +215,38 @@ public class BatteryUtils {
        return (powerUsageMah / (totalPowerMah - hiddenPowerMah)) * dischargeAmount;
    }

    /**
     * Calculate the whole running time in the state {@code statsType}
     *
     * @param batteryStatsHelper utility class that contains the data
     * @param statsType state that we want to calculate the time for
     * @return the running time in millis
     */
    public long calculateRunningTimeBasedOnStatsType(BatteryStatsHelper batteryStatsHelper,
            int statsType) {
        final long elapsedRealtimeUs = convertMsToUs(SystemClock.elapsedRealtime());
        // Return the battery time (millisecond) on status mStatsType
        return convertUsToMs(
                batteryStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs, statsType));

    }

    /**
     * Find the package name for a {@link android.os.BatteryStats.Uid}
     *
     * @param uid id to get the package name
     * @return the package name. If there are multiple packages related to
     * given id, return the first one. Or return null if there are no known
     * packages with the given id
     *
     * @see PackageManager#getPackagesForUid(int)
     */
    public String getPackageName(int uid) {
        final String[] packageNames = mPackageManager.getPackagesForUid(uid);

        return ArrayUtils.isEmpty(packageNames) ? null : packageNames[0];
    }

    private long convertUsToMs(long timeUs) {
        return timeUs / 1000;
    }
+2 −9
Original line number Diff line number Diff line
@@ -499,7 +499,8 @@ public class PowerUsageSummary extends PowerUsageBase implements
        BatteryInfo batteryInfo = getBatteryInfo(elapsedRealtimeUs, batteryBroadcast);
        updateHeaderPreference(batteryInfo);

        final long runningTime = calculateRunningTimeBasedOnStatsType();
        final long runningTime = mBatteryUtils.calculateRunningTimeBasedOnStatsType(mStatsHelper,
                mStatsType);
        updateScreenPreference();
        updateLastFullChargePreference(runningTime);

@@ -655,14 +656,6 @@ public class PowerUsageSummary extends PowerUsageBase implements
                        timeSequence));
    }

    @VisibleForTesting
    long calculateRunningTimeBasedOnStatsType() {
        final long elapsedRealtimeUs = mBatteryUtils.convertMsToUs(SystemClock.elapsedRealtime());
        // Return the battery time (millisecond) on status mStatsType
        return mStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs,
                mStatsType /* STATS_SINCE_CHARGED */) / 1000;
    }

    @VisibleForTesting
    void updateHeaderPreference(BatteryInfo info) {
        final Context context = getContext();
+6 −2
Original line number Diff line number Diff line
@@ -34,9 +34,11 @@ import java.util.Objects;
 */
public class Anomaly implements Parcelable {
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({AnomalyType.WAKE_LOCK})
    @IntDef({AnomalyType.WAKE_LOCK,
            AnomalyType.WAKEUP_ALARM})
    public @interface AnomalyType {
        int WAKE_LOCK = 0;
        int WAKEUP_ALARM = 1;
    }

    @Retention(RetentionPolicy.SOURCE)
@@ -46,7 +48,9 @@ public class Anomaly implements Parcelable {
    }

    @AnomalyType
    public static final int[] ANOMALY_TYPE_LIST = {AnomalyType.WAKE_LOCK};
    public static final int[] ANOMALY_TYPE_LIST =
            {AnomalyType.WAKE_LOCK,
            AnomalyType.WAKEUP_ALARM};

    /**
     * Type of this this anomaly
+1 −7
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
            // TODO: add more attributes to detect wakelock anomaly
            if (maxPartialWakeLockMs > WAKE_LOCK_THRESHOLD_MS
                    && !mBatteryUtils.shouldHideSipper(sipper)) {
                final String packageName = getPackageName(uid.getUid());
                final String packageName = mBatteryUtils.getPackageName(uid.getUid());
                final CharSequence displayName = Utils.getApplicationLabel(mContext,
                        packageName);

@@ -101,12 +101,6 @@ public class WakeLockAnomalyDetector implements AnomalyDetector {
        return anomalies;
    }

    private String getPackageName(int uid) {
        final String[] packageNames = mPackageManager.getPackagesForUid(uid);

        return packageNames == null ? null : packageNames[0];
    }

    @VisibleForTesting
    long getTotalDurationMs(BatteryStats.Timer timer, long rawRealtime) {
        if (timer == null) {
+107 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 com.android.settings.fuelgauge.anomaly.checker;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.BatteryStats;
import android.os.SystemClock;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.util.ArrayMap;

import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.anomaly.Anomaly;
import com.android.settings.fuelgauge.anomaly.AnomalyDetectionPolicy;

import java.util.ArrayList;
import java.util.List;

/**
 * Check whether apps has too many wakeup alarms
 */
public class WakeupAlarmAnomalyDetector implements AnomalyDetector {
    private static final String TAG = "WakeupAlarmAnomalyDetector";
    //TODO: add this threshold into AnomalyDetectionPolicy
    private static final int WAKEUP_ALARM_THRESHOLD = 60;
    private Context mContext;
    @VisibleForTesting
    BatteryUtils mBatteryUtils;

    public WakeupAlarmAnomalyDetector(Context context) {
        mContext = context;
        mBatteryUtils = BatteryUtils.getInstance(context);
    }

    @Override
    public List<Anomaly> detectAnomalies(BatteryStatsHelper batteryStatsHelper) {
        final List<BatterySipper> batterySippers = batteryStatsHelper.getUsageList();
        final List<Anomaly> anomalies = new ArrayList<>();
        final long totalRunningHours = mBatteryUtils.calculateRunningTimeBasedOnStatsType(
                batteryStatsHelper, BatteryStats.STATS_SINCE_CHARGED) / DateUtils.HOUR_IN_MILLIS;

        if (totalRunningHours != 0) {
            for (int i = 0, size = batterySippers.size(); i < size; i++) {
                final BatterySipper sipper = batterySippers.get(i);
                final BatteryStats.Uid uid = sipper.uidObj;
                if (uid == null || mBatteryUtils.shouldHideSipper(sipper)) {
                    continue;
                }

                final int wakeups = getWakeupAlarmCountFromUid(uid);
                if ((wakeups / totalRunningHours) > WAKEUP_ALARM_THRESHOLD) {
                    final String packageName = mBatteryUtils.getPackageName(uid.getUid());
                    final CharSequence displayName = Utils.getApplicationLabel(mContext,
                            packageName);

                    Anomaly anomaly = new Anomaly.Builder()
                            .setUid(uid.getUid())
                            .setType(Anomaly.AnomalyType.WAKEUP_ALARM)
                            .setDisplayName(displayName)
                            .setPackageName(packageName)
                            .build();
                    anomalies.add(anomaly);
                }
            }
        }

        return anomalies;
    }

    @VisibleForTesting
    int getWakeupAlarmCountFromUid(BatteryStats.Uid uid) {
        int wakeups = 0;
        final ArrayMap<String, ? extends BatteryStats.Uid.Pkg> packageStats
                = uid.getPackageStats();
        for (int ipkg = packageStats.size() - 1; ipkg >= 0; ipkg--) {
            final BatteryStats.Uid.Pkg ps = packageStats.valueAt(ipkg);
            final ArrayMap<String, ? extends BatteryStats.Counter> alarms =
                    ps.getWakeupAlarmStats();
            for (int iwa = alarms.size() - 1; iwa >= 0; iwa--) {
                int count = alarms.valueAt(iwa).getCountLocked(BatteryStats.STATS_SINCE_CHARGED);
                wakeups += count;
            }

        }

        return wakeups;
    }

}
Loading