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

Commit cef373c7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support Private Space in battery usage." into main

parents 167f9d41 c9e8b8a0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -556,9 +556,11 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
                String.format(
                        "getBatterySinceLastFullChargeUsageData() size=%d time=%d/ms",
                        batteryHistoryMap.size(), (System.currentTimeMillis() - start)));

        final Map<Integer, Map<Integer, BatteryDiffData>> batteryUsageData =
                DataProcessor.getBatteryUsageData(context, batteryHistoryMap);
                DataProcessor.getBatteryUsageData(
                        context,
                        new UserIdsSeries(context, /* mainUserOnly= */ false),
                        batteryHistoryMap);
        if (batteryUsageData == null) {
            return null;
        }
+11 −5
Original line number Diff line number Diff line
@@ -84,12 +84,12 @@ public final class BatteryUsageDataLoader {
    }

    @VisibleForTesting
    static void loadAppUsageData(final Context context) {
    static void loadAppUsageData(final Context context, final UserIdsSeries userIdsSeries) {
        final long start = System.currentTimeMillis();
        final Map<Long, UsageEvents> appUsageEvents =
                sFakeAppUsageEventsSupplier != null
                        ? sFakeAppUsageEventsSupplier.get()
                        : DataProcessor.getAppUsageEvents(context);
                        : DataProcessor.getAppUsageEvents(context, userIdsSeries);
        if (appUsageEvents == null) {
            Log.w(TAG, "loadAppUsageData() returns null");
            return;
@@ -113,13 +113,15 @@ public final class BatteryUsageDataLoader {
        DatabaseUtils.sendAppUsageEventData(context, appUsageEventList);
    }

    private static void preprocessBatteryUsageSlots(final Context context) {
    private static void preprocessBatteryUsageSlots(
            final Context context, final UserIdsSeries userIdsSeries) {
        final long start = System.currentTimeMillis();
        final Handler handler = new Handler(Looper.getMainLooper());
        final BatteryLevelData batteryLevelData =
                DataProcessManager.getBatteryLevelData(
                        context,
                        handler,
                        userIdsSeries,
                        /* isFromPeriodJob= */ true,
                        batteryDiffDataMap -> {
                            DatabaseUtils.sendBatteryUsageSlotData(
@@ -162,8 +164,12 @@ public final class BatteryUsageDataLoader {
            loadBatteryStatsData(context, isFullChargeStart);
            if (!isFullChargeStart) {
                // No app usage data or battery diff data at this time.
                loadAppUsageData(context);
                preprocessBatteryUsageSlots(context);
                final UserIdsSeries userIdsSeries =
                        new UserIdsSeries(context, /* mainUserOnly= */ true);
                if (!userIdsSeries.isCurrentUserLocked()) {
                    loadAppUsageData(context, userIdsSeries);
                    preprocessBatteryUsageSlots(context, userIdsSeries);
                }
            }
            Log.d(
                    TAG,
+44 −59
Original line number Diff line number Diff line
@@ -21,8 +21,6 @@ import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.Log;

@@ -30,7 +28,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.Utils;

import java.util.ArrayList;
import java.util.Calendar;
@@ -82,7 +79,7 @@ public class DataProcessManager {
    private final long mLastFullChargeTimestamp;
    private final Context mContext;
    private final Handler mHandler;
    private final UserManager mUserManager;
    private final UserIdsSeries mUserIdsSeries;
    private final OnBatteryDiffDataMapLoadedListener mCallbackFunction;
    private final List<AppUsageEvent> mAppUsageEventList = new ArrayList<>();
    private final List<BatteryEvent> mBatteryEventList = new ArrayList<>();
@@ -123,6 +120,7 @@ public class DataProcessManager {
    DataProcessManager(
            Context context,
            Handler handler,
            final UserIdsSeries userIdsSeries,
            final long rawStartTimestamp,
            final long lastFullChargeTimestamp,
            @NonNull final OnBatteryDiffDataMapLoadedListener callbackFunction,
@@ -130,7 +128,7 @@ public class DataProcessManager {
            @NonNull final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
        mContext = context.getApplicationContext();
        mHandler = handler;
        mUserManager = mContext.getSystemService(UserManager.class);
        mUserIdsSeries = userIdsSeries;
        mRawStartTimestamp = rawStartTimestamp;
        mLastFullChargeTimestamp = lastFullChargeTimestamp;
        mCallbackFunction = callbackFunction;
@@ -142,10 +140,11 @@ public class DataProcessManager {
    DataProcessManager(
            Context context,
            Handler handler,
            final UserIdsSeries userIdsSeries,
            @NonNull final OnBatteryDiffDataMapLoadedListener callbackFunction) {
        mContext = context.getApplicationContext();
        mHandler = handler;
        mUserManager = mContext.getSystemService(UserManager.class);
        mUserIdsSeries = userIdsSeries;
        mCallbackFunction = callbackFunction;
        mRawStartTimestamp = 0L;
        mLastFullChargeTimestamp = 0L;
@@ -175,10 +174,18 @@ public class DataProcessManager {
                // Loads the latest app usage list from the service.
                loadCurrentAppUsageList();
                // Loads existing battery usage slots from database.
                if (mUserIdsSeries.isMainUserProfileOnly()) {
                    loadBatteryUsageSlotList();
                } else {
                    mIsBatteryUsageSlotLoaded = true;
                }
            }
            // Loads app usage list from database.
            if (mUserIdsSeries.isMainUserProfileOnly()) {
                loadDatabaseAppUsageList();
            } else {
                mIsDatabaseAppUsageLoaded = true;
            }
            // Loads the battery event list from database.
            loadPowerConnectionBatteryEventList();
        } else {
@@ -264,6 +271,7 @@ public class DataProcessManager {
    private void loadCurrentAppUsageList() {
        new AsyncTask<Void, Void, List<AppUsageEvent>>() {
            @Override
            @Nullable
            protected List<AppUsageEvent> doInBackground(Void... voids) {
                if (!shouldLoadAppUsageData()) {
                    Log.d(TAG, "not loadCurrentAppUsageList");
@@ -271,33 +279,21 @@ public class DataProcessManager {
                }
                final long startTime = System.currentTimeMillis();
                // Loads the current battery usage data from the battery stats service.
                final int currentUserId = getCurrentUserId();
                final int workProfileUserId = getWorkProfileUserId();
                final Map<Long, UsageEvents> usageEventsMap = new ArrayMap<>();
                for (int userId : mUserIdsSeries.getVisibleUserIds()) {
                    final UsageEvents usageEventsForCurrentUser =
                        DataProcessor.getAppUsageEventsForUser(
                                mContext, currentUserId, mRawStartTimestamp);
                // If fail to load usage events for current user, return null directly and screen-on
                // time will not be shown in the UI.
                            DataProcessor.getCurrentAppUsageEventsForUser(
                                    mContext, mUserIdsSeries, userId, mRawStartTimestamp);
                    if (usageEventsForCurrentUser == null) {
                    Log.w(TAG, "usageEventsForCurrentUser is null");
                        // If fail to load usage events for any user, return null directly and
                        // screen-on time will not be shown in the UI.
                        if (userId == mUserIdsSeries.getCurrentUserId()) {
                            return null;
                        }
                UsageEvents usageEventsForWorkProfile = null;
                if (workProfileUserId != Integer.MIN_VALUE) {
                    usageEventsForWorkProfile =
                            DataProcessor.getAppUsageEventsForUser(
                                    mContext, workProfileUserId, mRawStartTimestamp);
                    } else {
                    Log.d(TAG, "there is no work profile");
                        usageEventsMap.put(Long.valueOf(userId), usageEventsForCurrentUser);
                    }

                final Map<Long, UsageEvents> usageEventsMap = new ArrayMap<>();
                usageEventsMap.put(Long.valueOf(currentUserId), usageEventsForCurrentUser);
                if (usageEventsForWorkProfile != null) {
                    Log.d(TAG, "usageEventsForWorkProfile is null");
                    usageEventsMap.put(Long.valueOf(workProfileUserId), usageEventsForWorkProfile);
                }

                final List<AppUsageEvent> appUsageEventList =
                        DataProcessor.generateAppUsageEventListFromUsageEvents(
                                mContext, usageEventsMap);
@@ -337,7 +333,7 @@ public class DataProcessManager {
                        DatabaseUtils.getAppUsageEventForUsers(
                                mContext,
                                Calendar.getInstance(),
                                getCurrentUserIds(),
                                mUserIdsSeries.getVisibleUserIds(),
                                mRawStartTimestamp);
                Log.d(
                        TAG,
@@ -435,6 +431,7 @@ public class DataProcessManager {
                final Map<Long, BatteryDiffData> batteryDiffDataMap =
                        DataProcessor.getBatteryDiffDataMapFromStatsService(
                                mContext,
                                mUserIdsSeries,
                                mRawStartTimestamp,
                                getSystemAppsPackageNames(),
                                getSystemAppsUids());
@@ -514,6 +511,7 @@ public class DataProcessManager {
                batteryDiffDataMap.putAll(
                        DataProcessor.getBatteryDiffDataMap(
                                mContext,
                                mUserIdsSeries,
                                mHourlyBatteryLevelsPerDay,
                                mBatteryHistoryMap,
                                mAppUsagePeriodMap,
@@ -546,9 +544,8 @@ public class DataProcessManager {
        if (!mShowScreenOnTime) {
            return false;
        }
        final int currentUserId = getCurrentUserId();
        // If current user is locked, no need to load app usage data from service or database.
        if (mUserManager == null || !mUserManager.isUserUnlocked(currentUserId)) {
        if (mUserIdsSeries.isCurrentUserLocked()) {
            Log.d(TAG, "shouldLoadAppUsageData: false, current user is locked");
            mShowScreenOnTime = false;
            return false;
@@ -556,26 +553,6 @@ public class DataProcessManager {
        return true;
    }

    // Returns the list of current user id and work profile id if exists.
    private List<Integer> getCurrentUserIds() {
        final List<Integer> userIds = new ArrayList<>();
        userIds.add(getCurrentUserId());
        final int workProfileUserId = getWorkProfileUserId();
        if (workProfileUserId != Integer.MIN_VALUE) {
            userIds.add(workProfileUserId);
        }
        return userIds;
    }

    private int getCurrentUserId() {
        return mContext.getUserId();
    }

    private int getWorkProfileUserId() {
        final UserHandle userHandle = Utils.getManagedProfile(mUserManager);
        return userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;
    }

    private synchronized Set<String> getSystemAppsPackageNames() {
        if (mSystemAppsPackageNames == null) {
            mSystemAppsPackageNames = DataProcessor.getSystemAppsPackageNames(mContext);
@@ -599,6 +576,7 @@ public class DataProcessManager {
    public static BatteryLevelData getBatteryLevelData(
            Context context,
            @Nullable Handler handler,
            final UserIdsSeries userIdsSeries,
            final boolean isFromPeriodJob,
            final OnBatteryDiffDataMapLoadedListener onBatteryUsageMapLoadedListener) {
        final long start = System.currentTimeMillis();
@@ -610,13 +588,14 @@ public class DataProcessManager {
                        lastFullChargeTime,
                        DatabaseUtils.BATTERY_LEVEL_RECORD_EVENTS);
        final long startTimestamp =
                batteryLevelRecordEvents.isEmpty()
                (batteryLevelRecordEvents.isEmpty() || !userIdsSeries.isMainUserProfileOnly())
                        ? lastFullChargeTime
                        : batteryLevelRecordEvents.get(0).getTimestamp();
        final BatteryLevelData batteryLevelData =
                getPeriodBatteryLevelData(
                        context,
                        handler,
                        userIdsSeries,
                        startTimestamp,
                        lastFullChargeTime,
                        isFromPeriodJob,
@@ -636,6 +615,7 @@ public class DataProcessManager {
    private static BatteryLevelData getPeriodBatteryLevelData(
            Context context,
            @Nullable Handler handler,
            final UserIdsSeries userIdsSeries,
            final long startTimestamp,
            final long lastFullChargeTime,
            final boolean isFromPeriodJob,
@@ -663,7 +643,9 @@ public class DataProcessManager {
                                lastFullChargeTime);
        if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
            Log.d(TAG, "batteryHistoryMap is null in getPeriodBatteryLevelData()");
            new DataProcessManager(context, handler, onBatteryDiffDataMapLoadedListener).start();
            new DataProcessManager(
                            context, handler, userIdsSeries, onBatteryDiffDataMapLoadedListener)
                    .start();
            return null;
        }

@@ -675,7 +657,9 @@ public class DataProcessManager {
                DataProcessor.getLevelDataThroughProcessedHistoryMap(
                        context, processedBatteryHistoryMap);
        if (batteryLevelData == null) {
            new DataProcessManager(context, handler, onBatteryDiffDataMapLoadedListener).start();
            new DataProcessManager(
                            context, handler, userIdsSeries, onBatteryDiffDataMapLoadedListener)
                    .start();
            Log.d(TAG, "getBatteryLevelData() returns null");
            return null;
        }
@@ -684,6 +668,7 @@ public class DataProcessManager {
        new DataProcessManager(
                        context,
                        handler,
                        userIdsSeries,
                        startTimestamp,
                        lastFullChargeTime,
                        onBatteryDiffDataMapLoadedListener,
+26 −43
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.BatteryConsumer;
import android.os.BatteryStatsManager;
import android.os.BatteryUsageStats;
@@ -52,7 +51,6 @@ import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.PowerProfile;
import com.android.settings.Utils;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.fuelgauge.BatteryStatus;
@@ -134,6 +132,7 @@ public final class DataProcessor {
    @Nullable
    public static Map<Integer, Map<Integer, BatteryDiffData>> getBatteryUsageData(
            Context context,
            UserIdsSeries userIdsSeries,
            @Nullable final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap) {
        if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
            Log.d(TAG, "getBatteryLevelData() returns null");
@@ -161,6 +160,7 @@ public final class DataProcessor {
                        context,
                        getBatteryDiffDataMap(
                                context,
                                userIdsSeries,
                                batteryLevelData.getHourlyBatteryLevelsPerDay(),
                                processedBatteryHistoryMap,
                                /* appUsagePeriodMap= */ null,
@@ -183,24 +183,21 @@ public final class DataProcessor {

    /** Gets the {@link UsageEvents} from system service for all unlocked users. */
    @Nullable
    public static Map<Long, UsageEvents> getAppUsageEvents(Context context) {
    public static Map<Long, UsageEvents> getAppUsageEvents(
            Context context, UserIdsSeries userIdsSeries) {
        final long start = System.currentTimeMillis();
        context = DatabaseUtils.getParentContext(context);
        if (context == null) {
            return null;
        }
        final Map<Long, UsageEvents> resultMap = new ArrayMap();
        final UserManager userManager = context.getSystemService(UserManager.class);
        if (userManager == null) {
            return null;
        }
        final long sixDaysAgoTimestamp =
                DatabaseUtils.getTimestampSixDaysAgo(Calendar.getInstance());
        for (final UserInfo user : userManager.getAliveUsers()) {
        for (final int userId : userIdsSeries.getVisibleUserIds()) {
            final UsageEvents events =
                    getAppUsageEventsForUser(context, userManager, user.id, sixDaysAgoTimestamp);
                    getAppUsageEventsForUser(context, userIdsSeries, userId, sixDaysAgoTimestamp);
            if (events != null) {
                resultMap.put(Long.valueOf(user.id), events);
                resultMap.put(Long.valueOf(userId), events);
            }
        }
        final long elapsedTime = System.currentTimeMillis() - start;
@@ -212,22 +209,21 @@ public final class DataProcessor {

    /** Gets the {@link UsageEvents} from system service for the specific user. */
    @Nullable
    public static UsageEvents getAppUsageEventsForUser(
            Context context, final int userID, final long startTimestampOfLevelData) {
    public static UsageEvents getCurrentAppUsageEventsForUser(
            Context context,
            final UserIdsSeries userIdsSeries,
            final int userID,
            final long startTimestampOfLevelData) {
        final long start = System.currentTimeMillis();
        context = DatabaseUtils.getParentContext(context);
        if (context == null) {
            return null;
        }
        final UserManager userManager = context.getSystemService(UserManager.class);
        if (userManager == null) {
            return null;
        }
        final long sixDaysAgoTimestamp =
                DatabaseUtils.getTimestampSixDaysAgo(Calendar.getInstance());
        final long earliestTimestamp = Math.max(sixDaysAgoTimestamp, startTimestampOfLevelData);
        final UsageEvents events =
                getAppUsageEventsForUser(context, userManager, userID, earliestTimestamp);
                getAppUsageEventsForUser(context, userIdsSeries, userID, earliestTimestamp);
        final long elapsedTime = System.currentTimeMillis() - start;
        Log.d(
                TAG,
@@ -521,6 +517,7 @@ public final class DataProcessor {

    static Map<Long, BatteryDiffData> getBatteryDiffDataMap(
            Context context,
            final UserIdsSeries userIdsSeries,
            final List<BatteryLevelData.PeriodBatteryLevelData> hourlyBatteryLevelsPerDay,
            final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
            final Map<Integer, Map<Integer, Map<Long, Map<String, List<AppUsagePeriod>>>>>
@@ -528,11 +525,6 @@ public final class DataProcessor {
            final @NonNull Set<String> systemAppsPackageNames,
            final @NonNull Set<Integer> systemAppsUids) {
        final Map<Long, BatteryDiffData> batteryDiffDataMap = new ArrayMap<>();
        final int currentUserId = context.getUserId();
        final UserHandle userHandle =
                Utils.getManagedProfile(context.getSystemService(UserManager.class));
        final int workProfileUserId =
                userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;
        // Each time slot usage diff data =
        //     sum(Math.abs(timestamp[i+1] data - timestamp[i] data));
        // since we want to aggregate every hour usage diff data into a single time slot.
@@ -569,8 +561,7 @@ public final class DataProcessor {
                                endTimestamp,
                                startBatteryLevel,
                                endBatteryLevel,
                                currentUserId,
                                workProfileUserId,
                                userIdsSeries,
                                slotDuration,
                                systemAppsPackageNames,
                                systemAppsUids,
@@ -629,6 +620,7 @@ public final class DataProcessor {
    @Nullable
    static BatteryDiffData generateBatteryDiffData(
            final Context context,
            final UserIdsSeries userIdsSeries,
            final long startTimestamp,
            final List<BatteryHistEntry> batteryHistEntryList,
            final @NonNull Set<String> systemAppsPackageNames,
@@ -650,15 +642,9 @@ public final class DataProcessor {
                    systemAppsUids,
                    /* isAccumulated= */ false);
        }
        final int currentUserId = context.getUserId();
        final UserHandle userHandle =
                Utils.getManagedProfile(context.getSystemService(UserManager.class));
        final int workProfileUserId =
                userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;

        for (BatteryHistEntry entry : batteryHistEntryList) {
            final boolean isFromOtherUsers =
                    isConsumedFromOtherUsers(currentUserId, workProfileUserId, entry);
                    isConsumedFromOtherUsers(userIdsSeries, entry);
            // Not show other users' battery usage data.
            if (isFromOtherUsers) {
                continue;
@@ -905,6 +891,7 @@ public final class DataProcessor {

    static Map<Long, BatteryDiffData> getBatteryDiffDataMapFromStatsService(
            final Context context,
            final UserIdsSeries userIdsSeries,
            final long startTimestamp,
            @NonNull final Set<String> systemAppsPackageNames,
            @NonNull final Set<Integer> systemAppsUids) {
@@ -913,6 +900,7 @@ public final class DataProcessor {
                startTimestamp,
                generateBatteryDiffData(
                        context,
                        userIdsSeries,
                        startTimestamp,
                        getBatteryHistListFromFromStatsService(context),
                        systemAppsPackageNames,
@@ -1034,14 +1022,14 @@ public final class DataProcessor {
    @Nullable
    private static UsageEvents getAppUsageEventsForUser(
            Context context,
            final UserManager userManager,
            final UserIdsSeries userIdsSeries,
            final int userID,
            final long earliestTimestamp) {
        final String callingPackage = context.getPackageName();
        final long now = System.currentTimeMillis();
        // When the user is not unlocked, UsageStatsManager will return null, so bypass the
        // following data loading logics directly.
        if (!userManager.isUserUnlocked(userID)) {
        if (userIdsSeries.isUserLocked(userID)) {
            Log.w(TAG, "fail to load app usage event for user :" + userID + " because locked");
            return null;
        }
@@ -1331,8 +1319,7 @@ public final class DataProcessor {
            final long endTimestamp,
            final int startBatteryLevel,
            final int endBatteryLevel,
            final int currentUserId,
            final int workProfileUserId,
            final UserIdsSeries userIdsSeries,
            final long slotDuration,
            final Set<String> systemAppsPackageNames,
            final Set<Integer> systemAppsUids,
@@ -1342,8 +1329,7 @@ public final class DataProcessor {
        if (appUsageMap != null) {
            final List<AppUsagePeriod> flatAppUsagePeriodList = new ArrayList<>();
            for (final long userId : appUsageMap.keySet()) {
                if ((userId != currentUserId && userId != workProfileUserId)
                        || appUsageMap.get(userId) == null) {
                if (userIdsSeries.isFromOtherUsers(userId) || appUsageMap.get(userId) == null) {
                    continue;
                }
                for (final String packageName : appUsageMap.get(userId).keySet()) {
@@ -1405,8 +1391,7 @@ public final class DataProcessor {

            // Not show other users' battery usage data.
            final boolean isFromOtherUsers =
                    isConsumedFromOtherUsers(
                            currentUserId, workProfileUserId, selectedBatteryEntry);
                    isConsumedFromOtherUsers(userIdsSeries, selectedBatteryEntry);
            if (isFromOtherUsers) {
                continue;
            }
@@ -1593,12 +1578,10 @@ public final class DataProcessor {
    }

    private static boolean isConsumedFromOtherUsers(
            final int currentUserId,
            final int workProfileUserId,
            final UserIdsSeries userIdsSeries,
            final BatteryHistEntry batteryHistEntry) {
        return isUidConsumer(batteryHistEntry.mConsumerType)
                && batteryHistEntry.mUserId != currentUserId
                && batteryHistEntry.mUserId != workProfileUserId;
                && userIdsSeries.isFromOtherUsers(batteryHistEntry.mUserId);
    }

    @Nullable
+1 −0
Original line number Diff line number Diff line
@@ -492,6 +492,7 @@ public class PowerUsageAdvanced extends PowerUsageBase {
                    return DataProcessManager.getBatteryLevelData(
                            getContext(),
                            mHandler,
                            new UserIdsSeries(getContext(), /* mainUserOnly= */ false),
                            /* isFromPeriodJob= */ false,
                            PowerUsageAdvanced.this::onBatteryDiffDataMapUpdate);
                }
Loading