diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java index 51dce26fdf4..5e6d7d59c88 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartPreferenceController.java @@ -556,9 +556,11 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll String.format( "getBatterySinceLastFullChargeUsageData() size=%d time=%d/ms", batteryHistoryMap.size(), (System.currentTimeMillis() - start))); - final Map> batteryUsageData = - DataProcessor.getBatteryUsageData(context, batteryHistoryMap); + DataProcessor.getBatteryUsageData( + context, + new UserIdsSeries(context, /* mainUserOnly= */ false), + batteryHistoryMap); if (batteryUsageData == null) { return null; } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java index fb5b9a1a327..d1bf0d21c0d 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoader.java @@ -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 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, diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java index b3bcb47ecc5..3e8df615d53 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessManager.java @@ -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 mAppUsageEventList = new ArrayList<>(); private final List 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> 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. - loadBatteryUsageSlotList(); + if (mUserIdsSeries.isMainUserProfileOnly()) { + loadBatteryUsageSlotList(); + } else { + mIsBatteryUsageSlotLoaded = true; + } } // Loads app usage list from database. - loadDatabaseAppUsageList(); + 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>() { @Override + @Nullable protected List 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 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. - if (usageEventsForCurrentUser == null) { - Log.w(TAG, "usageEventsForCurrentUser is null"); - 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"); - } - final Map usageEventsMap = new ArrayMap<>(); - usageEventsMap.put(Long.valueOf(currentUserId), usageEventsForCurrentUser); - if (usageEventsForWorkProfile != null) { - Log.d(TAG, "usageEventsForWorkProfile is null"); - usageEventsMap.put(Long.valueOf(workProfileUserId), usageEventsForWorkProfile); + for (int userId : mUserIdsSeries.getVisibleUserIds()) { + final UsageEvents usageEventsForCurrentUser = + DataProcessor.getCurrentAppUsageEventsForUser( + mContext, mUserIdsSeries, userId, mRawStartTimestamp); + if (usageEventsForCurrentUser == 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; + } + } else { + usageEventsMap.put(Long.valueOf(userId), usageEventsForCurrentUser); + } } - final List 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 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 getCurrentUserIds() { - final List 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 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, diff --git a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java index 2ef12f18007..da8481d3a13 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java +++ b/src/com/android/settings/fuelgauge/batteryusage/DataProcessor.java @@ -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> getBatteryUsageData( Context context, + UserIdsSeries userIdsSeries, @Nullable final Map> 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 getAppUsageEvents(Context context) { + public static Map getAppUsageEvents( + Context context, UserIdsSeries userIdsSeries) { final long start = System.currentTimeMillis(); context = DatabaseUtils.getParentContext(context); if (context == null) { return null; } final Map 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 getBatteryDiffDataMap( Context context, + final UserIdsSeries userIdsSeries, final List hourlyBatteryLevelsPerDay, final Map> batteryHistoryMap, final Map>>>> @@ -528,11 +525,6 @@ public final class DataProcessor { final @NonNull Set systemAppsPackageNames, final @NonNull Set systemAppsUids) { final Map 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 batteryHistEntryList, final @NonNull Set 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 getBatteryDiffDataMapFromStatsService( final Context context, + final UserIdsSeries userIdsSeries, final long startTimestamp, @NonNull final Set systemAppsPackageNames, @NonNull final Set 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 systemAppsPackageNames, final Set systemAppsUids, @@ -1342,8 +1329,7 @@ public final class DataProcessor { if (appUsageMap != null) { final List 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 diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java index 29839e91802..f5ed06ddcee 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java @@ -492,6 +492,7 @@ public class PowerUsageAdvanced extends PowerUsageBase { return DataProcessManager.getBatteryLevelData( getContext(), mHandler, + new UserIdsSeries(getContext(), /* mainUserOnly= */ false), /* isFromPeriodJob= */ false, PowerUsageAdvanced.this::onBatteryDiffDataMapUpdate); } diff --git a/src/com/android/settings/fuelgauge/batteryusage/UserIdsSeries.java b/src/com/android/settings/fuelgauge/batteryusage/UserIdsSeries.java new file mode 100644 index 00000000000..3dc311e7248 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batteryusage/UserIdsSeries.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2024 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.content.Context; +import android.content.pm.UserInfo; +import android.os.UserManager; + +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; + +class UserIdsSeries { + private final UserManager mUserManager; + private final int mCurrentUserId; + private final List mVisibleUserIds = new ArrayList<>(); + + @Nullable private UserInfo mPrivateUser = null; + @Nullable private UserInfo mManagedProfileUser = null; + + UserIdsSeries(final Context context, final boolean mainUserOnly) { + mUserManager = context.getSystemService(UserManager.class); + mCurrentUserId = context.getUserId(); + List aliveUsers = + mUserManager != null ? mUserManager.getAliveUsers() : new ArrayList<>(); + + if (mainUserOnly) { + aliveUsers.stream() + .filter(UserInfo::isMain) + .forEach(userInfo -> mVisibleUserIds.add(userInfo.id)); + return; + } + + for (UserInfo userInfo : aliveUsers) { + if (!mUserManager.isSameProfileGroup(mCurrentUserId, userInfo.id)) { + continue; + } + if (!userInfo.isQuietModeEnabled() || userInfo.isManagedProfile()) { + mVisibleUserIds.add(userInfo.id); + } + if (userInfo.isPrivateProfile()) { + mPrivateUser = userInfo; + } + if (userInfo.isManagedProfile()) { + mManagedProfileUser = userInfo; + } + } + } + + int getCurrentUserId() { + return mCurrentUserId; + } + + List getVisibleUserIds() { + return mVisibleUserIds; + } + + boolean isCurrentUserLocked() { + return isUserLocked(mCurrentUserId); + } + + boolean isUserLocked(int userId) { + return mUserManager == null || !mUserManager.isUserUnlocked(userId); + } + + boolean isFromOtherUsers(long userId) { + return !mVisibleUserIds.contains((int) userId); + } + + boolean isMainUserProfileOnly() { + return mUserManager != null + && mUserManager.isMainUser() + && mPrivateUser == null + && mManagedProfileUser == null; + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java index 723a13826cf..41379b3a85c 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryUsageDataLoaderTest.java @@ -52,6 +52,7 @@ import java.util.List; public final class BatteryUsageDataLoaderTest { private Context mContext; + @Mock private UserIdsSeries mUserIdsSeries; @Mock private ContentResolver mMockContentResolver; @Mock private BatteryStatsManager mBatteryStatsManager; @Mock private PackageManager mPackageManager; @@ -120,7 +121,7 @@ public final class BatteryUsageDataLoaderTest { BatteryUsageDataLoader.sFakeAppUsageEventsSupplier = () -> new HashMap<>(); BatteryUsageDataLoader.sFakeUsageEventsListSupplier = () -> AppUsageEventList; - BatteryUsageDataLoader.loadAppUsageData(mContext); + BatteryUsageDataLoader.loadAppUsageData(mContext, mUserIdsSeries); verify(mMockContentResolver).bulkInsert(any(), any()); verify(mMockContentResolver).notifyChange(any(), any()); @@ -130,7 +131,7 @@ public final class BatteryUsageDataLoaderTest { public void loadAppUsageData_nullAppUsageEvents_notInsertDataIntoProvider() { BatteryUsageDataLoader.sFakeAppUsageEventsSupplier = () -> null; - BatteryUsageDataLoader.loadAppUsageData(mContext); + BatteryUsageDataLoader.loadAppUsageData(mContext, mUserIdsSeries); verifyNoMoreInteractions(mMockContentResolver); } @@ -140,7 +141,7 @@ public final class BatteryUsageDataLoaderTest { BatteryUsageDataLoader.sFakeAppUsageEventsSupplier = () -> new HashMap<>(); BatteryUsageDataLoader.sFakeUsageEventsListSupplier = () -> null; - BatteryUsageDataLoader.loadAppUsageData(mContext); + BatteryUsageDataLoader.loadAppUsageData(mContext, mUserIdsSeries); verifyNoMoreInteractions(mMockContentResolver); } @@ -150,7 +151,7 @@ public final class BatteryUsageDataLoaderTest { BatteryUsageDataLoader.sFakeAppUsageEventsSupplier = () -> new HashMap<>(); BatteryUsageDataLoader.sFakeUsageEventsListSupplier = () -> new ArrayList<>(); - BatteryUsageDataLoader.loadAppUsageData(mContext); + BatteryUsageDataLoader.loadAppUsageData(mContext, mUserIdsSeries); verifyNoMoreInteractions(mMockContentResolver); } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java index 6227790b3dd..b025db8d551 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessManagerTest.java @@ -70,6 +70,7 @@ public final class DataProcessManagerTest { private Context mContext; private DataProcessManager mDataProcessManager; + @Mock private UserIdsSeries mUserIdsSeries; @Mock private IUsageStatsManager mUsageStatsManager; @Mock private UserManager mUserManager; @Mock private BatteryStatsManager mBatteryStatsManager; @@ -95,11 +96,13 @@ public final class DataProcessManagerTest { doReturn(mIntent).when(mContext).registerReceiver(any(), any()); doReturn(100).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_SCALE), anyInt()); doReturn(66).when(mIntent).getIntExtra(eq(BatteryManager.EXTRA_LEVEL), anyInt()); + doReturn(true).when(mUserIdsSeries).isMainUserProfileOnly(); mDataProcessManager = new DataProcessManager( mContext, /* handler= */ null, + mUserIdsSeries, /* rawStartTimestamp= */ 0L, /* lastFullChargeTimestamp= */ 0L, /* callbackFunction= */ null, @@ -117,7 +120,11 @@ public final class DataProcessManagerTest { @LooperMode(LooperMode.Mode.LEGACY) public void constructor_noLevelData() { final DataProcessManager dataProcessManager = - new DataProcessManager(mContext, /* handler= */ null, /* callbackFunction= */ null); + new DataProcessManager( + mContext, + /* handler= */ null, + mUserIdsSeries, + /* callbackFunction= */ null); assertThat(dataProcessManager.getShowScreenOnTime()).isFalse(); } @@ -180,6 +187,7 @@ public final class DataProcessManagerTest { doReturn(1).when(mContext).getUserId(); // No work profile. doReturn(new ArrayList<>()).when(mUserManager).getUserProfiles(); + doReturn(new ArrayList<>(List.of(1))).when(mUserIdsSeries).getVisibleUserIds(); // Fake database usage data. final MatrixCursor cursor = @@ -239,6 +247,7 @@ public final class DataProcessManagerTest { new DataProcessManager( mContext, /* handler= */ null, + mUserIdsSeries, /* rawStartTimestamp= */ 2L, /* lastFullChargeTimestamp= */ 1L, /* callbackFunction= */ null, @@ -301,7 +310,7 @@ public final class DataProcessManagerTest { doReturn(getUsageEvents(events)) .when(mUsageStatsManager) .queryEventsForUser(anyLong(), anyLong(), anyInt(), any()); - doReturn(false).when(mUserManager).isUserUnlocked(anyInt()); + doReturn(true).when(mUserIdsSeries).isCurrentUserLocked(); final MatrixCursor cursor = new MatrixCursor( new String[] { @@ -327,6 +336,7 @@ public final class DataProcessManagerTest { DataProcessManager.getBatteryLevelData( mContext, /* handler= */ null, + mUserIdsSeries, /* isFromPeriodJob= */ false, /* asyncResponseDelegate= */ null)) .isNull(); @@ -334,6 +344,7 @@ public final class DataProcessManagerTest { DataProcessManager.getBatteryLevelData( mContext, /* handler= */ null, + mUserIdsSeries, /* isFromPeriodJob= */ true, /* asyncResponseDelegate= */ null)) .isNull(); @@ -355,6 +366,7 @@ public final class DataProcessManagerTest { DataProcessManager.getBatteryLevelData( mContext, /* handler= */ null, + mUserIdsSeries, /* isFromPeriodJob= */ false, /* asyncResponseDelegate= */ null); @@ -383,6 +395,7 @@ public final class DataProcessManagerTest { DataProcessManager.getBatteryLevelData( mContext, /* handler= */ null, + mUserIdsSeries, /* isFromPeriodJob= */ false, /* asyncResponseDelegate= */ null); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java index 7a672401d1c..28973430ce9 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/DataProcessorTest.java @@ -80,6 +80,7 @@ public final class DataProcessorTest { @Mock private Intent mIntent; @Mock private BatteryUsageStats mBatteryUsageStats; @Mock private UserManager mUserManager; + @Mock private UserIdsSeries mUserIdsSeries; @Mock private IUsageStatsManager mUsageStatsManager; @Mock private BatteryEntry mMockBatteryEntry1; @Mock private BatteryEntry mMockBatteryEntry2; @@ -95,6 +96,7 @@ public final class DataProcessorTest { mContext = spy(RuntimeEnvironment.application); mFeatureFactory = FakeFeatureFactory.setupForTest(); mPowerUsageFeatureProvider = mFeatureFactory.powerUsageFeatureProvider; + doReturn(true).when(mUserIdsSeries).isMainUserProfileOnly(); DataProcessor.sTestSystemAppsPackageNames = Set.of(); DataProcessor.sUsageStatsManager = mUsageStatsManager; @@ -118,8 +120,10 @@ public final class DataProcessorTest { doReturn(mUsageEvents1) .when(mUsageStatsManager) .queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()); + doReturn(new ArrayList<>(List.of(0))).when(mUserIdsSeries).getVisibleUserIds(); - final Map resultMap = DataProcessor.getAppUsageEvents(mContext); + final Map resultMap = + DataProcessor.getAppUsageEvents(mContext, mUserIdsSeries); assertThat(resultMap).hasSize(1); assertThat(resultMap.get(Long.valueOf(userInfo.id))).isEqualTo(mUsageEvents1); @@ -134,7 +138,8 @@ public final class DataProcessorTest { // Test locked user. doReturn(false).when(mUserManager).isUserUnlocked(userInfo.id); - final Map resultMap = DataProcessor.getAppUsageEvents(mContext); + final Map resultMap = + DataProcessor.getAppUsageEvents(mContext, mUserIdsSeries); assertThat(resultMap).isNull(); } @@ -150,7 +155,8 @@ public final class DataProcessorTest { .when(mUsageStatsManager) .queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()); - final Map resultMap = DataProcessor.getAppUsageEvents(mContext); + final Map resultMap = + DataProcessor.getAppUsageEvents(mContext, mUserIdsSeries); assertThat(resultMap).isNull(); } @@ -163,7 +169,8 @@ public final class DataProcessorTest { .when(mUsageStatsManager) .queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()); - assertThat(DataProcessor.getAppUsageEventsForUser(mContext, userId, 0)) + assertThat(DataProcessor.getCurrentAppUsageEventsForUser( + mContext, mUserIdsSeries, userId, 0)) .isEqualTo(mUsageEvents1); } @@ -173,7 +180,9 @@ public final class DataProcessorTest { // Test locked user. doReturn(false).when(mUserManager).isUserUnlocked(userId); - assertThat(DataProcessor.getAppUsageEventsForUser(mContext, userId, 0)).isNull(); + assertThat(DataProcessor.getCurrentAppUsageEventsForUser( + mContext, mUserIdsSeries, userId, 0)) + .isNull(); } @Test @@ -184,7 +193,9 @@ public final class DataProcessorTest { .when(mUsageStatsManager) .queryEventsForUser(anyLong(), anyLong(), anyInt(), anyString()); - assertThat(DataProcessor.getAppUsageEventsForUser(mContext, userId, 0)).isNull(); + assertThat(DataProcessor.getCurrentAppUsageEventsForUser( + mContext, mUserIdsSeries, userId, 0)) + .isNull(); } @Test @@ -852,6 +863,7 @@ public final class DataProcessorTest { assertThat( DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, hourlyBatteryLevelsPerDay, new HashMap<>(), /* appUsagePeriodMap= */ null, @@ -938,6 +950,7 @@ public final class DataProcessorTest { Map batteryDiffDataMap = DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, appUsagePeriodMap, @@ -1154,6 +1167,7 @@ public final class DataProcessorTest { mContext, DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, appUsagePeriodMap, @@ -1271,6 +1285,10 @@ public final class DataProcessorTest { }; final Map> batteryHistoryMap = new HashMap<>(); final int currentUserId = mContext.getUserId(); + doReturn(false).when(mUserIdsSeries).isFromOtherUsers(currentUserId); + doReturn(true).when(mUserIdsSeries).isFromOtherUsers(currentUserId + 1); + doReturn(true).when(mUserIdsSeries).isFromOtherUsers(currentUserId + 2); + // Adds the index = 0 data. Map entryMap = new HashMap<>(); BatteryHistEntry entry = @@ -1431,6 +1449,7 @@ public final class DataProcessorTest { mContext, DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, /* appUsagePeriodMap= */ null, @@ -1546,6 +1565,7 @@ public final class DataProcessorTest { mContext, DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, appUsagePeriodMap, @@ -1701,6 +1721,7 @@ public final class DataProcessorTest { mContext, DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, /* appUsagePeriodMap= */ null, @@ -1851,6 +1872,7 @@ public final class DataProcessorTest { mContext, DataProcessor.getBatteryDiffDataMap( mContext, + mUserIdsSeries, batteryLevelData.getHourlyBatteryLevelsPerDay(), batteryHistoryMap, /* appUsagePeriodMap= */ null, @@ -1873,6 +1895,7 @@ public final class DataProcessorTest { final BatteryDiffData batteryDiffData = DataProcessor.generateBatteryDiffData( mContext, + mUserIdsSeries, System.currentTimeMillis(), DataProcessor.convertToBatteryHistEntry(null, mBatteryUsageStats), /* systemAppsPackageNames= */ Set.of(), @@ -1933,6 +1956,7 @@ public final class DataProcessorTest { final BatteryDiffData batteryDiffData = DataProcessor.generateBatteryDiffData( mContext, + mUserIdsSeries, System.currentTimeMillis(), DataProcessor.convertToBatteryHistEntry( batteryEntryList, mBatteryUsageStats),