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

Commit 6e242c29 authored by Kuan Wang's avatar Kuan Wang Committed by Android (Google) Code Review
Browse files

Merge "Use the field isFullChargeCycleStart in database to get the last full...

Merge "Use the field isFullChargeCycleStart in database to get the last full charge cycle start and remove the unused SharedPreference."
parents 9ee0556e 2b93d406
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -80,6 +80,6 @@ public final class BatteryUsageBroadcastReceiver extends BroadcastReceiver {
        }

        mFetchBatteryUsageData = true;
        BatteryUsageDataLoader.enqueueWork(context);
        BatteryUsageDataLoader.enqueueWork(context, /*isFullChargeStart=*/ true);
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -40,9 +40,8 @@ import java.time.Duration;
public class BatteryUsageContentProvider extends ContentProvider {
    private static final String TAG = "BatteryUsageContentProvider";

    // TODO: Updates the duration to a more reasonable value for since-last-full-charge.
    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public static final Duration QUERY_DURATION_HOURS = Duration.ofHours(28);
    public static final Duration QUERY_DURATION_HOURS = Duration.ofDays(6);

    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
    public static final String QUERY_KEY_TIMESTAMP = "timestamp";
@@ -141,7 +140,7 @@ public class BatteryUsageContentProvider extends ContentProvider {
        final long timestamp = mClock.millis();
        Cursor cursor = null;
        try {
            cursor = mBatteryStateDao.getCursorAfter(firstTimestamp);
            cursor = mBatteryStateDao.getCursorSinceLastFullCharge(firstTimestamp);
        } catch (RuntimeException e) {
            Log.e(TAG, "query() from:" + uri + " error:" + e);
        }
+7 −6
Original line number Diff line number Diff line
@@ -37,15 +37,15 @@ public final class BatteryUsageDataLoader {
    private BatteryUsageDataLoader() {
    }

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

    @VisibleForTesting
    static void loadUsageData(Context context) {
    static void loadUsageData(final Context context, final boolean isFullChargeStart) {
        final long start = System.currentTimeMillis();
        final BatteryUsageStats batteryUsageStats = DataProcessor.getBatteryUsageStats(context);
        final List<BatteryEntry> batteryEntryList =
@@ -60,13 +60,14 @@ public final class BatteryUsageDataLoader {

        // Uploads the BatteryEntry data into SettingsIntelligence.
        DatabaseUtils.sendBatteryEntryData(
                context, batteryEntryList, batteryUsageStats);
                context, batteryEntryList, batteryUsageStats, isFullChargeStart);
        DataProcessor.closeBatteryUsageStats(batteryUsageStats);
    }

    private static void loadUsageDataSafely(Context context) {
    private static void loadUsageDataSafely(
            final Context context, final boolean isFullChargeStart) {
        try {
            loadUsageData(context);
            loadUsageData(context, isFullChargeStart);
        } catch (RuntimeException e) {
            Log.e(TAG, "loadUsageData:" + e);
        }
+6 −2
Original line number Diff line number Diff line
@@ -92,7 +92,8 @@ public final class ConvertUtils {
            final int batteryStatus,
            final int batteryHealth,
            final long bootTimestamp,
            final long timestamp) {
            final long timestamp,
            final boolean isFullChargeStart) {
        final ContentValues values = new ContentValues();
        if (entry != null && batteryUsageStats != null) {
            values.put(BatteryHistEntry.KEY_UID, Long.valueOf(entry.getUid()));
@@ -106,6 +107,8 @@ public final class ConvertUtils {
            values.put(BatteryHistEntry.KEY_PACKAGE_NAME, FAKE_PACKAGE_NAME);
        }
        values.put(BatteryHistEntry.KEY_TIMESTAMP, Long.valueOf(timestamp));
        values.put(BatteryHistEntry.KEY_IS_FULL_CHARGE_CYCLE_START,
                Boolean.valueOf(isFullChargeStart));
        final BatteryInformation batteryInformation =
                constructBatteryInformation(
                        entry,
@@ -163,7 +166,8 @@ public final class ConvertUtils {
                        /*batteryStatus=*/ 0,
                        /*batteryHealth=*/ 0,
                        /*bootTimestamp=*/ 0,
                        /*timestamp=*/ 0));
                        /*timestamp=*/ 0,
                        /*isFullChargeStart=*/ false));
    }

    /** Converts UTC timestamp to human readable local time string. */
+16 −56
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
@@ -37,7 +36,6 @@ import androidx.annotation.VisibleForTesting;

import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batteryusage.db.BatteryStateDatabase;
import com.android.settingslib.fuelgauge.BatteryStatus;

import java.time.Clock;
import java.time.Duration;
@@ -50,8 +48,6 @@ import java.util.Map;
/** A utility class to operate battery usage database. */
public final class DatabaseUtils {
    private static final String TAG = "DatabaseUtils";
    private static final String PREF_FILE_NAME = "battery_module_preference";
    private static final String PREF_FULL_CHARGE_TIMESTAMP_KEY = "last_full_charge_timestamp_key";
    /** Key for query parameter timestamp used in BATTERY_CONTENT_URI **/
    private static final String QUERY_KEY_TIMESTAMP = "timestamp";
    /** Clear memory threshold for device booting phase. **/
@@ -89,8 +85,8 @@ public final class DatabaseUtils {
    public static Map<Long, Map<String, BatteryHistEntry>> getHistoryMapSinceLastFullCharge(
            Context context, Calendar calendar) {
        final long startTime = System.currentTimeMillis();
        final long lastFullChargeTimestamp =
                getStartTimestampForLastFullCharge(context, calendar);
        final long sixDaysAgoTimestamp = getTimestampSixDaysAgo(calendar);
        Log.d(TAG, "sixDayAgoTimestamp: " + sixDaysAgoTimestamp);
        // Builds the content uri everytime to avoid cache.
        final Uri batteryStateUri =
                new Uri.Builder()
@@ -98,7 +94,7 @@ public final class DatabaseUtils {
                        .authority(AUTHORITY)
                        .appendPath(BATTERY_STATE_TABLE)
                        .appendQueryParameter(
                                QUERY_KEY_TIMESTAMP, Long.toString(lastFullChargeTimestamp))
                                QUERY_KEY_TIMESTAMP, Long.toString(sixDaysAgoTimestamp))
                        .build();

        final Map<Long, Map<String, BatteryHistEntry>> resultMap =
@@ -142,9 +138,10 @@ public final class DatabaseUtils {
    }

    static List<ContentValues> sendBatteryEntryData(
            Context context,
            List<BatteryEntry> batteryEntryList,
            BatteryUsageStats batteryUsageStats) {
            final Context context,
            final List<BatteryEntry> batteryEntryList,
            final BatteryUsageStats batteryUsageStats,
            final boolean isFullChargeStart) {
        final long startTime = System.currentTimeMillis();
        final Intent intent = BatteryUtils.getBatteryIntent(context);
        if (intent == null) {
@@ -186,7 +183,8 @@ public final class DatabaseUtils {
                                    batteryStatus,
                                    batteryHealth,
                                    snapshotBootTimestamp,
                                    snapshotTimestamp)));
                                    snapshotTimestamp,
                                    isFullChargeStart)));
        }

        int size = 1;
@@ -197,6 +195,8 @@ public final class DatabaseUtils {
            valuesList.toArray(valuesArray);
            try {
                size = resolver.bulkInsert(BATTERY_CONTENT_URI, valuesArray);
                Log.d(TAG, "insert() data into database with isFullChargeStart:"
                        + isFullChargeStart);
            } catch (Exception e) {
                Log.e(TAG, "bulkInsert() data into database error:\n" + e);
            }
@@ -210,15 +210,18 @@ public final class DatabaseUtils {
                            batteryStatus,
                            batteryHealth,
                            snapshotBootTimestamp,
                            snapshotTimestamp);
                            snapshotTimestamp,
                            isFullChargeStart);
            try {
                resolver.insert(BATTERY_CONTENT_URI, contentValues);
                Log.d(TAG, "insert() data into database with isFullChargeStart:"
                        + isFullChargeStart);

            } catch (Exception e) {
                Log.e(TAG, "insert() data into database error:\n" + e);
            }
            valuesList.add(contentValues);
        }
        saveLastFullChargeTimestampPref(context, batteryStatus, batteryLevel, snapshotTimestamp);
        resolver.notifyChange(BATTERY_CONTENT_URI, /*observer=*/ null);
        Log.d(TAG, String.format("sendBatteryEntryData() size=%d in %d/ms",
                size, (System.currentTimeMillis() - startTime)));
@@ -226,42 +229,6 @@ public final class DatabaseUtils {
        return valuesList;
    }

    @VisibleForTesting
    static void saveLastFullChargeTimestampPref(
            Context context, int batteryStatus, int batteryLevel, long timestamp) {
        // Updates the SharedPreference only when timestamp is valid and phone is full charge.
        if (!BatteryStatus.isCharged(batteryStatus, batteryLevel)) {
            return;
        }

        final boolean success =
                getSharedPreferences(context)
                        .edit()
                        .putLong(PREF_FULL_CHARGE_TIMESTAMP_KEY, timestamp)
                        .commit();
        if (!success) {
            Log.w(TAG, "saveLastFullChargeTimestampPref() fail: value=" + timestamp);
        }
    }

    @VisibleForTesting
    static long getLastFullChargeTimestampPref(Context context) {
        return getSharedPreferences(context).getLong(PREF_FULL_CHARGE_TIMESTAMP_KEY, 0);
    }

    /**
     * Returns the start timestamp for "since last full charge" battery usage chart.
     * If the last full charge happens within the last 7 days, returns the timestamp of last full
     * charge. Otherwise, returns the timestamp for 00:00 6 days before the calendar date.
     */
    @VisibleForTesting
    static long getStartTimestampForLastFullCharge(
            Context context, Calendar calendar) {
        final long lastFullChargeTimestamp = getLastFullChargeTimestampPref(context);
        final long sixDayAgoTimestamp = getTimestampSixDaysAgo(calendar);
        return Math.max(lastFullChargeTimestamp, sixDayAgoTimestamp);
    }

    private static Map<Long, Map<String, BatteryHistEntry>> loadHistoryMapFromContentProvider(
            Context context, Uri batteryStateUri) {
        final boolean isWorkProfileUser = isWorkProfile(context);
@@ -313,13 +280,6 @@ public final class DatabaseUtils {
        }, CLEAR_MEMORY_DELAYED_MS);
    }

    private static SharedPreferences getSharedPreferences(Context context) {
        return context
                .getApplicationContext() // ensures we bind it with application
                .createDeviceProtectedStorageContext()
                .getSharedPreferences(PREF_FILE_NAME, Context.MODE_PRIVATE);
    }

    /** Returns the timestamp for 00:00 6 days before the calendar date. */
    private static long getTimestampSixDaysAgo(Calendar calendar) {
        Calendar startCalendar =
Loading