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

Commit f76ba118 authored by ykhung's avatar ykhung
Browse files

Adopt new battery history map with interpolation method

Bug: 184807417
Test: make SettingsRoboTests
Change-Id: I5c45a443d0a72df352d4bb707412328ad009f6d4
parent 953b7e3b
Loading
Loading
Loading
Loading
+23 −41
Original line number Diff line number Diff line
@@ -53,8 +53,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        implements PreferenceControllerMixin, LifecycleObserver, OnPause, OnDestroy,
                BatteryChartView.OnSelectListener, ExpandDividerPreference.OnExpandListener {
    private static final String TAG = "BatteryChartPreferenceController";
    private static final int CHART_KEY_ARRAY_SIZE = 25;
    /** Desired battery history size for timestamp slots. */
    public static final int DESIRED_HISTORY_SIZE = 25;
    private static final int CHART_LEVEL_ARRAY_SIZE = 13;
    private static final int CHART_KEY_ARRAY_SIZE = DESIRED_HISTORY_SIZE;
    private static final long VALID_USAGE_TIME_DURATION = DateUtils.HOUR_IN_MILLIS * 2;
    private static final long VALID_DIFF_DURATION = DateUtils.MINUTE_IN_MILLIS * 3;

@@ -176,12 +178,12 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    }

    void setBatteryHistoryMap(
            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
        mHandler.post(() -> setBatteryHistoryMapInner(batteryHistoryMap));
    }

    private void setBatteryHistoryMapInner(
            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
        // Resets all battery history data relative variables.
        if (batteryHistoryMap == null) {
            mBatteryIndexedMap = null;
@@ -189,31 +191,32 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            mBatteryHistoryLevels = null;
            return;
        }
        // Generates battery history keys.
        // Generates battery history timestamp slots.
        final List<Long> batteryHistoryKeyList =
            new ArrayList<Long>(batteryHistoryMap.keySet());
            new ArrayList<>(batteryHistoryMap.keySet());
        Collections.sort(batteryHistoryKeyList);
        validateSlotTimestamp(batteryHistoryKeyList);
        mBatteryHistoryKeys = new long[CHART_KEY_ARRAY_SIZE];
        final int listSize = batteryHistoryKeyList.size();
        final int elementSize = Math.min(listSize, CHART_KEY_ARRAY_SIZE);
        for (int index = 0; index < elementSize; index++) {
            mBatteryHistoryKeys[CHART_KEY_ARRAY_SIZE - index - 1] =
                batteryHistoryKeyList.get(listSize - index - 1);
        for (int index = 0; index < CHART_KEY_ARRAY_SIZE; index++) {
            mBatteryHistoryKeys[index] = batteryHistoryKeyList.get(index);
        }

        // Generates the battery history levels.
        // Generates the battery history levels for chart graph.
        mBatteryHistoryLevels = new int[CHART_LEVEL_ARRAY_SIZE];
        for (int index = 0; index < CHART_LEVEL_ARRAY_SIZE; index++) {
            final Long timestamp = Long.valueOf(mBatteryHistoryKeys[index * 2]);
            final List<BatteryHistEntry> entryList = batteryHistoryMap.get(timestamp);
            if (entryList != null && !entryList.isEmpty()) {
                // All battery levels are the same in the same timestamp snapshot.
                mBatteryHistoryLevels[index] = entryList.get(0).mBatteryLevel;
            } else if (entryList != null && entryList.isEmpty()) {
                Log.e(TAG, "abnormal entry list in the timestamp:" +
                    ConvertUtils.utcToLocalTime(timestamp));
            final long timestamp = mBatteryHistoryKeys[index * 2];
            final Map<String, BatteryHistEntry> entryMap = batteryHistoryMap.get(timestamp);
            if (entryMap == null || entryMap.isEmpty()) {
                Log.e(TAG, "abnormal entry list in the timestamp:"
                    + ConvertUtils.utcToLocalTime(timestamp));
                continue;
            }
            // Averages the battery level in each time slot to avoid corner conditions.
            float batteryLevelCounter = 0;
            for (BatteryHistEntry entry : entryMap.values()) {
                batteryLevelCounter += entry.mBatteryLevel;
            }
            mBatteryHistoryLevels[index] =
                Math.round(batteryLevelCounter / entryMap.size());
        }
        // Generates indexed usage map for chart.
        mBatteryIndexedMap =
@@ -532,25 +535,4 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        }
        return true;
    }

    @VisibleForTesting
    static boolean validateSlotTimestamp(List<Long> batteryHistoryKeys) {
        // Whether the nearest two slot time diff is valid or not?
        final int size = batteryHistoryKeys.size();
        for (int index = 0; index < size - 1; index++) {
            final long currentTime = batteryHistoryKeys.get(index);
            final long nextTime = batteryHistoryKeys.get(index + 1);
            final long diffTime = Math.abs(
                DateUtils.HOUR_IN_MILLIS - Math.abs(currentTime - nextTime));
            if (currentTime == 0) {
                continue;
            } else if (diffTime > VALID_DIFF_DURATION) {
                Log.e(TAG, String.format("validateSlotTimestamp() %s > %s",
                    ConvertUtils.utcToLocalTime(currentTime),
                    ConvertUtils.utcToLocalTime(nextTime)));
                return false;
            }
        }
        return true;
    }
}
+3 −4
Original line number Diff line number Diff line
@@ -20,12 +20,11 @@ import android.content.Context;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.utils.AsyncLoaderCompat;

import java.util.List;
import java.util.Map;

/** Loader that can be used to load battery history information. */
public class BatteryHistoryLoader
        extends AsyncLoaderCompat<Map<Long, List<BatteryHistEntry>>> {
        extends AsyncLoaderCompat<Map<Long, Map<String, BatteryHistEntry>>> {
    private static final String TAG = "BatteryHistoryLoader";

    private final Context mContext;
@@ -36,11 +35,11 @@ public class BatteryHistoryLoader
    }

    @Override
    protected void onDiscardResult(Map<Long, List<BatteryHistEntry>> result) {
    protected void onDiscardResult(Map<Long, Map<String, BatteryHistEntry>> result) {
    }

    @Override
    public Map<Long, List<BatteryHistEntry>> loadInBackground() {
    public Map<Long, Map<String, BatteryHistEntry>> loadInBackground() {
        final PowerUsageFeatureProvider powerUsageFeatureProvider =
            FeatureFactory.getFactory(mContext).getPowerUsageFeatureProvider(mContext);
        return powerUsageFeatureProvider.getBatteryHistory(mContext);
+4 −25
Original line number Diff line number Diff line
@@ -144,30 +144,9 @@ public final class ConvertUtils {
            final Context context,
            final int timeSlotSize,
            final long[] batteryHistoryKeys,
            final Map<Long, List<BatteryHistEntry>> batteryHistoryMap,
            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
            final boolean purgeLowPercentageData) {
        final Map<Integer, List<BatteryDiffEntry>> resultMap = new HashMap<>();
        // Generates a temporary map to calculate diff usage data, which converts the inputted
        // List<BatteryDiffEntry> into Map<String, BatteryHistEntry> with the key comes from
        // the BatteryHistEntry.getKey() method.
        final Map<Long, Map<String, BatteryHistEntry>> newBatteryHistoryMap = new HashMap<>();
        for (int index = 0; index < batteryHistoryKeys.length; index++) {
            final Long timestamp = Long.valueOf(batteryHistoryKeys[index]);
            final List<BatteryHistEntry> entries = batteryHistoryMap.get(timestamp);
            if (entries == null || entries.isEmpty()) {
                continue;
            }
            final Map<String, BatteryHistEntry> slotBatteryHistDataMap = new HashMap<>();
            for (BatteryHistEntry entry : entries) {
                // Excludes auto-generated fake BatteryHistEntry data,
                // which is used to record battery level and status purpose only.
                if (!FAKE_PACKAGE_NAME.equals(entry.mPackageName)) {
                    slotBatteryHistDataMap.put(entry.getKey(), entry);
                }
            }
            newBatteryHistoryMap.put(timestamp, slotBatteryHistDataMap);
        }

        // Each time slot usage diff data =
        //     Math.abs(timestamp[i+2] data - timestamp[i+1] data) +
        //     Math.abs(timestamp[i+1] data - timestamp[i] data);
@@ -188,11 +167,11 @@ public final class ConvertUtils {

            // Fetches BatteryHistEntry data from corresponding time slot.
            final Map<String, BatteryHistEntry> currentBatteryHistMap =
                newBatteryHistoryMap.getOrDefault(currentTimestamp, EMPTY_BATTERY_MAP);
                batteryHistoryMap.getOrDefault(currentTimestamp, EMPTY_BATTERY_MAP);
            final Map<String, BatteryHistEntry> nextBatteryHistMap =
                newBatteryHistoryMap.getOrDefault(nextTimestamp, EMPTY_BATTERY_MAP);
                batteryHistoryMap.getOrDefault(nextTimestamp, EMPTY_BATTERY_MAP);
            final Map<String, BatteryHistEntry> nextTwoBatteryHistMap =
                newBatteryHistoryMap.getOrDefault(nextTwoTimestamp, EMPTY_BATTERY_MAP);
                batteryHistoryMap.getOrDefault(nextTwoTimestamp, EMPTY_BATTERY_MAP);

            // Collects all keys in these three time slot records as population.
            final Set<String> allBatteryHistEntryKeys = new HashSet<>();
+7 −6
Original line number Diff line number Diff line
@@ -52,7 +52,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
    @VisibleForTesting
    BatteryHistoryPreference mHistPref;
    @VisibleForTesting
    Map<Long, List<BatteryHistEntry>> mBatteryHistoryMap;
    Map<Long, Map<String, BatteryHistEntry>> mBatteryHistoryMap;
    @VisibleForTesting
    final BatteryHistoryLoaderCallbacks mBatteryHistoryLoaderCallbacks =
            new BatteryHistoryLoaderCallbacks();
@@ -210,25 +210,26 @@ public class PowerUsageAdvanced extends PowerUsageBase {
            };

    private class BatteryHistoryLoaderCallbacks
            implements LoaderManager.LoaderCallbacks<Map<Long, List<BatteryHistEntry>>> {
            implements LoaderManager.LoaderCallbacks<Map<Long, Map<String, BatteryHistEntry>>> {
        private int mRefreshType;

        @Override
        @NonNull
        public Loader<Map<Long, List<BatteryHistEntry>>> onCreateLoader(int id, Bundle bundle) {
        public Loader<Map<Long, Map<String, BatteryHistEntry>>> onCreateLoader(
                int id, Bundle bundle) {
            mRefreshType = bundle.getInt(KEY_REFRESH_TYPE);
            return new BatteryHistoryLoader(getContext());
        }

        @Override
        public void onLoadFinished(Loader<Map<Long, List<BatteryHistEntry>>> loader,
                Map<Long, List<BatteryHistEntry>> batteryHistoryMap) {
        public void onLoadFinished(Loader<Map<Long, Map<String, BatteryHistEntry>>> loader,
                Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
            mBatteryHistoryMap = batteryHistoryMap;
            PowerUsageAdvanced.this.onLoadFinished(mRefreshType);
        }

        @Override
        public void onLoaderReset(Loader<Map<Long, List<BatteryHistEntry>>> loader) {
        public void onLoaderReset(Loader<Map<Long, Map<String, BatteryHistEntry>>> loader) {
        }
    }

+1 −2
Original line number Diff line number Diff line
@@ -23,7 +23,6 @@ import android.util.SparseIntArray;
import com.android.internal.os.BatterySipper;
import com.android.settingslib.fuelgauge.Estimate;

import java.util.List;
import java.util.Map;

/**
@@ -136,5 +135,5 @@ public interface PowerUsageFeatureProvider {
    /**
     * Returns battery history data with corresponding timestamp key.
     */
    Map<Long, List<BatteryHistEntry>> getBatteryHistory(Context context);
    Map<Long, Map<String, BatteryHistEntry>> getBatteryHistory(Context context);
}
Loading