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

Commit 92dcd78a authored by jackqdyulei's avatar jackqdyulei
Browse files

Change high usage detector logic

Based on the requirement, change it to detect:
"whether battery draining is larger than x in the last y hours"

Bug: 70570352
Test: RunSettingsRoboTests
Change-Id: I9fb1a9f2fe38d5d64681dafe26311aeab7f3fe9c
parent 6411b170
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ public class BatteryInfo {
        void onParsingDone();
    }

    private static void parse(BatteryStats stats, BatteryDataParser... parsers) {
    public static void parse(BatteryStats stats, BatteryDataParser... parsers) {
        long startWalltime = 0;
        long endWalltime = 0;
        long historyStart = 0;
+26 −0
Original line number Diff line number Diff line
@@ -19,9 +19,12 @@ package com.android.settings.fuelgauge.batterytip;
import android.content.Context;
import android.provider.Settings;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;
import android.util.KeyValueListParser;
import android.util.Log;

import java.time.Duration;

/**
 * Class to store the policy for battery tips, which comes from
 * {@link Settings.Global}
@@ -34,6 +37,8 @@ public class BatteryTipPolicy {
    private static final String KEY_BATTERY_SAVER_TIP_ENABLED = "battery_saver_tip_enabled";
    private static final String KEY_HIGH_USAGE_ENABLED = "high_usage_enabled";
    private static final String KEY_HIGH_USAGE_APP_COUNT = "high_usage_app_count";
    private static final String KEY_HIGH_USAGE_PERIOD_MS = "high_usage_period_ms";
    private static final String KEY_HIGH_USAGE_BATTERY_DRAINING = "high_usage_battery_draining";
    private static final String KEY_APP_RESTRICTION_ENABLED = "app_restriction_enabled";
    private static final String KEY_REDUCED_BATTERY_ENABLED = "reduced_battery_enabled";
    private static final String KEY_REDUCED_BATTERY_PERCENT = "reduced_battery_percent";
@@ -80,6 +85,24 @@ public class BatteryTipPolicy {
     */
    public final int highUsageAppCount;

    /**
     * The size of the window(milliseconds) for checking if the device is being heavily used
     *
     * @see Settings.Global#BATTERY_TIP_CONSTANTS
     * @see #KEY_HIGH_USAGE_PERIOD_MS
     */
    public final long highUsagePeriodMs;

    /**
     * The battery draining threshold to detect whether device is heavily used.
     * If battery drains more than {@link #highUsageBatteryDraining} in last {@link
     * #highUsagePeriodMs}, treat device as heavily used.
     *
     * @see Settings.Global#BATTERY_TIP_CONSTANTS
     * @see #KEY_HIGH_USAGE_BATTERY_DRAINING
     */
    public final int highUsageBatteryDraining;

    /**
     * {@code true} if app restriction tip is enabled
     *
@@ -143,6 +166,9 @@ public class BatteryTipPolicy {
        batterySaverTipEnabled = mParser.getBoolean(KEY_BATTERY_SAVER_TIP_ENABLED, true);
        highUsageEnabled = mParser.getBoolean(KEY_HIGH_USAGE_ENABLED, true);
        highUsageAppCount = mParser.getInt(KEY_HIGH_USAGE_APP_COUNT, 3);
        highUsagePeriodMs = mParser.getLong(KEY_HIGH_USAGE_PERIOD_MS,
                Duration.ofHours(2).toMillis());
        highUsageBatteryDraining = mParser.getInt(KEY_HIGH_USAGE_BATTERY_DRAINING, 25);
        appRestrictionEnabled = mParser.getBoolean(KEY_APP_RESTRICTION_ENABLED, true);
        reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, false);
        reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50);
+79 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.batterytip;

import android.os.BatteryStats;

import com.android.settings.fuelgauge.BatteryInfo;

/**
 * DataParser used to go through battery data and detect whether battery is
 * heavily used.
 */
public class HighUsageDataParser implements BatteryInfo.BatteryDataParser {
    /**
     * time period to check the battery usage
     */
    private final long mTimePeriodMs;
    /**
     * treat device as heavily used if battery usage is more than {@code threshold}. 1 means 1%
     * battery usage.
     */
    private int mThreshold;
    private long mEndTimeMs;
    private byte mEndBatteryLevel;
    private byte mLastPeriodBatteryLevel;
    private int mBatteryDrain;

    public HighUsageDataParser(long timePeriodMs, int threshold) {
        mTimePeriodMs = timePeriodMs;
        mThreshold = threshold;
    }

    @Override
    public void onParsingStarted(long startTime, long endTime) {
        mEndTimeMs = endTime;
    }

    @Override
    public void onDataPoint(long time, BatteryStats.HistoryItem record) {
        if (record.currentTime <= mEndTimeMs - mTimePeriodMs) {
            // Since onDataPoint is invoked sorted by time, so we could use this way to get the
            // closet battery level 'mTimePeriodMs' time ago.
            mLastPeriodBatteryLevel = record.batteryLevel;
        }
        mEndBatteryLevel = record.batteryLevel;
    }

    @Override
    public void onDataGap() {
        // do nothing
    }

    @Override
    public void onParsingDone() {
        mBatteryDrain = mLastPeriodBatteryLevel - mEndBatteryLevel;
    }

    /**
     * Return {@code true} if the battery drain in {@link #mTimePeriodMs} is too much
     */
    public boolean isDeviceHeavilyUsed() {
        return mBatteryDrain > mThreshold;
    }
}
+31 −18
Original line number Diff line number Diff line
@@ -19,13 +19,14 @@ package com.android.settings.fuelgauge.batterytip.detectors;
import android.content.Context;
import android.os.BatteryStats;
import android.support.annotation.VisibleForTesting;
import android.text.format.DateUtils;

import com.android.internal.os.BatterySipper;
import com.android.internal.os.BatteryStatsHelper;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
import com.android.settings.fuelgauge.batterytip.AppInfo;
import com.android.settings.fuelgauge.BatteryInfo;
import com.android.settings.fuelgauge.batterytip.HighUsageDataParser;
import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;

@@ -43,6 +44,8 @@ public class HighUsageDetector implements BatteryTipDetector {
    private List<AppInfo> mHighUsageAppList;
    private Context mContext;
    @VisibleForTesting
    HighUsageDataParser mDataParser;
    @VisibleForTesting
    BatteryUtils mBatteryUtils;

    public HighUsageDetector(Context context, BatteryTipPolicy policy,
@@ -52,13 +55,16 @@ public class HighUsageDetector implements BatteryTipDetector {
        mBatteryStatsHelper = batteryStatsHelper;
        mHighUsageAppList = new ArrayList<>();
        mBatteryUtils = BatteryUtils.getInstance(context);
        mDataParser = new HighUsageDataParser(mPolicy.highUsagePeriodMs,
                mPolicy.highUsageBatteryDraining);
    }

    @Override
    public BatteryTip detect() {
        final long screenUsageTimeMs = mBatteryUtils.calculateScreenUsageTime(mBatteryStatsHelper);
        //TODO(b/70570352): Change it to detect whether battery drops 25% in last 2 hours
        if (mPolicy.highUsageEnabled && screenUsageTimeMs > DateUtils.HOUR_IN_MILLIS) {
        if (mPolicy.highUsageEnabled) {
            parseBatteryData();
            if (mDataParser.isDeviceHeavilyUsed()) {
                final List<BatterySipper> batterySippers = mBatteryStatsHelper.getUsageList();
                for (int i = 0, size = batterySippers.size(); i < size; i++) {
                    final BatterySipper batterySipper = batterySippers.get(i);
@@ -67,7 +73,8 @@ public class HighUsageDetector implements BatteryTipDetector {
                                BatteryUtils.StatusType.FOREGROUND, batterySipper.uidObj,
                                BatteryStats.STATS_SINCE_CHARGED);
                        mHighUsageAppList.add(new AppInfo.Builder()
                            .setPackageName(mBatteryUtils.getPackageName(batterySipper.getUid()))
                                .setPackageName(
                                        mBatteryUtils.getPackageName(batterySipper.getUid()))
                                .setScreenOnTimeMs(foregroundTimeMs)
                                .build());
                    }
@@ -77,7 +84,13 @@ public class HighUsageDetector implements BatteryTipDetector {
                        Math.min(mPolicy.highUsageAppCount, mHighUsageAppList.size()));
                Collections.sort(mHighUsageAppList, Collections.reverseOrder());
            }
        }

        return new HighUsageTip(screenUsageTimeMs, mHighUsageAppList);
    }

    @VisibleForTesting
    void parseBatteryData() {
        BatteryInfo.parse(mBatteryStatsHelper.getStats(), mDataParser);
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import com.android.settings.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
@@ -54,7 +55,7 @@ public class BatteryTipLoaderTest {
            BatteryTip.TipType.BATTERY_SAVER,
            BatteryTip.TipType.LOW_BATTERY,
            BatteryTip.TipType.SUMMARY};
    @Mock
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private BatteryStatsHelper mBatteryStatsHelper;
    @Mock
    private PowerManager mPowerManager;
Loading