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

Commit 50da7fee authored by Zaiyue Xue's avatar Zaiyue Xue
Browse files

Battery usage page latency improvement (1-8)

Save battery slot diff data into database in hourly job. Then read the
saved diff data and only calculate the remaining data. This could speed
up the battery usage loading.

Bug: 261163071
Fix: 261163071
Test: manual
Change-Id: Icd4868ca9326b64b17ddbccdb0311e755dc68026
parent 83c8f47d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ android_library {
        "net-utils-framework-common",
        "app-usage-event-protos-lite",
        "battery-event-protos-lite",
        "battery-usage-slot-protos-lite",
        "power-anomaly-event-protos-lite",
        "settings-contextual-card-protos-lite",
        "settings-log-bridge-protos-lite",
+4 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.settings.fuelgauge;

import static com.android.settings.fuelgauge.batteryusage.ConvertUtils.isUserConsumer;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.backup.BackupManager;
@@ -41,7 +43,6 @@ import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
import com.android.settings.fuelgauge.batteryusage.BatteryDiffEntry;
import com.android.settings.fuelgauge.batteryusage.BatteryEntry;
import com.android.settings.fuelgauge.batteryusage.BatteryHistEntry;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.EntityHeaderController;
import com.android.settingslib.HelpUtils;
@@ -149,14 +150,13 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
            Context context, int sourceMetricsCategory,
            BatteryDiffEntry diffEntry, String usagePercent, String slotInformation,
            boolean showTimeInformation) {
        final BatteryHistEntry histEntry = diffEntry.mBatteryHistEntry;
        final LaunchBatteryDetailPageArgs launchArgs = new LaunchBatteryDetailPageArgs();
        // configure the launch argument.
        launchArgs.mUsagePercent = usagePercent;
        launchArgs.mPackageName = diffEntry.getPackageName();
        launchArgs.mAppLabel = diffEntry.getAppLabel();
        launchArgs.mSlotInformation = slotInformation;
        launchArgs.mUid = (int) histEntry.mUid;
        launchArgs.mUid = (int) diffEntry.mUid;
        launchArgs.mIconId = diffEntry.getAppIconId();
        launchArgs.mConsumedPower = (int) diffEntry.mConsumePower;
        if (showTimeInformation) {
@@ -164,7 +164,7 @@ public class AdvancedPowerUsageDetail extends DashboardFragment implements
            launchArgs.mBackgroundTimeMs = diffEntry.mBackgroundUsageTimeInMs;
            launchArgs.mScreenOnTimeMs = diffEntry.mScreenOnTimeInMs;
        }
        launchArgs.mIsUserEntry = histEntry.isUserEntry();
        launchArgs.mIsUserEntry = isUserConsumer(diffEntry.mConsumerType);
        startBatteryDetailPage(context, sourceMetricsCategory, launchArgs);
    }

+0 −83
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.batteryusage;

import android.app.usage.UsageEvents;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import androidx.annotation.VisibleForTesting;

import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

/** Load app usage events data in the background. */
public final class AppUsageDataLoader {
    private static final String TAG = "AppUsageDataLoader";

    // For testing only.
    @VisibleForTesting
    static Supplier<Map<Long, UsageEvents>> sFakeAppUsageEventsSupplier;
    @VisibleForTesting
    static Supplier<List<AppUsageEvent>> sFakeUsageEventsListSupplier;

    private AppUsageDataLoader() {}

    static void enqueueWork(final Context context) {
        AsyncTask.execute(() -> {
            Log.d(TAG, "loadAppUsageDataSafely() in the AsyncTask");
            loadAppUsageDataSafely(context.getApplicationContext());
        });
    }

    @VisibleForTesting
    static void loadAppUsageData(final Context context) {
        final long start = System.currentTimeMillis();
        final Map<Long, UsageEvents> appUsageEvents =
                sFakeAppUsageEventsSupplier != null
                        ? sFakeAppUsageEventsSupplier.get()
                        : DataProcessor.getAppUsageEvents(context);
        if (appUsageEvents == null) {
            Log.w(TAG, "loadAppUsageData() returns null");
            return;
        }
        final List<AppUsageEvent> appUsageEventList =
                sFakeUsageEventsListSupplier != null
                        ? sFakeUsageEventsListSupplier.get()
                        : DataProcessor.generateAppUsageEventListFromUsageEvents(
                                context, appUsageEvents);
        if (appUsageEventList == null || appUsageEventList.isEmpty()) {
            Log.w(TAG, "loadAppUsageData() returns null or empty content");
            return;
        }
        final long elapsedTime = System.currentTimeMillis() - start;
        Log.d(TAG, String.format("loadAppUsageData() size=%d in %d/ms", appUsageEventList.size(),
                elapsedTime));
        // Uploads the AppUsageEvent data into database.
        DatabaseUtils.sendAppUsageEventData(context, appUsageEventList);
    }

    private static void loadAppUsageDataSafely(final Context context) {
        try {
            loadAppUsageData(context);
        } catch (RuntimeException e) {
            Log.e(TAG, "loadAppUsageData:" + e);
        }
    }
}
+13 −21
Original line number Diff line number Diff line
@@ -125,7 +125,6 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    Map<Integer, Map<Integer, BatteryDiffData>> mBatteryUsageMap;

    private boolean mIs24HourFormat;
    private boolean mHourlyChartVisible = true;
    private View mBatteryChartViewGroup;
    private TextView mChartSummaryTextView;
    private BatteryChartViewModel mDailyViewModel;
@@ -227,20 +226,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        mOnBatteryTipsUpdatedListener = listener;
    }

    void setBatteryHistoryMap(
            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
        Log.d(TAG, "setBatteryHistoryMap() " + (batteryHistoryMap == null ? "null"
                : ("size=" + batteryHistoryMap.size())));
        // Ensure the battery chart group is visible for users.
        animateBatteryChartViewGroup();
        final BatteryLevelData batteryLevelData =
                DataProcessManager.getBatteryLevelData(mContext, mHandler, batteryHistoryMap,
                        batteryUsageMap -> {
                            mBatteryUsageMap = batteryUsageMap;
                            logScreenUsageTime();
                            refreshUi();
                        });
        Log.d(TAG, "getBatteryLevelData: " + batteryLevelData);
    void onBatteryLevelDataUpdate(final BatteryLevelData batteryLevelData) {
        Log.d(TAG, "onBatteryLevelDataUpdate: " + batteryLevelData);
        mMetricsFeatureProvider.action(
                mPrefContext,
                SettingsEnums.ACTION_BATTERY_HISTORY_LOADED,
@@ -271,6 +258,13 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
        refreshUi();
    }

    void onBatteryUsageMapUpdate(Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageMap) {
        Log.d(TAG, "onBatteryUsageMapUpdate: " + batteryUsageMap);
        mBatteryUsageMap = batteryUsageMap;
        logScreenUsageTime();
        refreshUi();
    }

    void setBatteryChartView(@NonNull final BatteryChartView dailyChartView,
            @NonNull final BatteryChartView hourlyChartView) {
        final View parentView = (View) dailyChartView.getParent();
@@ -472,10 +466,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
    }

    private void animateBatteryHourlyChartView(final boolean visible) {
        if (mHourlyChartView == null || mHourlyChartVisible == visible) {
        if (mHourlyChartView == null
                || (mHourlyChartView.getVisibility() == View.VISIBLE) == visible) {
            return;
        }
        mHourlyChartVisible = visible;

        if (visible) {
            mHourlyChartView.setVisibility(View.VISIBLE);
@@ -632,10 +626,8 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
            return null;
        }
        for (BatteryDiffEntry entry : entries) {
            final BatteryHistEntry batteryHistEntry = entry.mBatteryHistEntry;
            if (batteryHistEntry != null
                    && batteryHistEntry.mConsumerType == ConvertUtils.CONSUMER_TYPE_UID_BATTERY
                    && batteryHistEntry.mUserId == userId
            if (!entry.isSystemEntry()
                    && entry.mUserId == userId
                    && packageName.equals(entry.getPackageName())) {
                return entry;
            }
+3 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.settings.fuelgauge.batteryusage;

import static com.android.settings.Utils.formatPercentage;
import static com.android.settings.fuelgauge.batteryusage.BatteryChartViewModel.AxisLabelPosition.BETWEEN_TRAPEZOIDS;
import static com.android.settingslib.fuelgauge.BatteryStatus.BATTERY_LEVEL_UNKNOWN;

import static java.lang.Math.abs;
import static java.lang.Math.round;
@@ -615,8 +616,8 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick

    private static boolean isTrapezoidValid(
            @NonNull BatteryChartViewModel viewModel, int trapezoidIndex) {
        return viewModel.getLevel(trapezoidIndex) != null
                && viewModel.getLevel(trapezoidIndex + 1) != null;
        return viewModel.getLevel(trapezoidIndex) != BATTERY_LEVEL_UNKNOWN
                && viewModel.getLevel(trapezoidIndex + 1) != BATTERY_LEVEL_UNKNOWN;
    }

    private static boolean isTrapezoidIndexValid(
Loading