Merge "Consolidate the bg exemption state changes from the pkgs with same UID" into tm-dev

This commit is contained in:
Jing Ji
2022-03-18 18:58:44 +00:00
committed by Android (Google) Code Review

View File

@@ -26,10 +26,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.os.SystemClock; import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.Pair; import android.util.Pair;
import android.util.Slog; import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.R; import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.server.am.AppBatteryExemptionTracker.AppBatteryExemptionPolicy; import com.android.server.am.AppBatteryExemptionTracker.AppBatteryExemptionPolicy;
import com.android.server.am.AppBatteryExemptionTracker.UidBatteryStates; import com.android.server.am.AppBatteryExemptionTracker.UidBatteryStates;
@@ -65,6 +68,11 @@ final class AppBatteryExemptionTracker
// As it's a UID-based tracker, anywhere which requires a package name, use this default name. // As it's a UID-based tracker, anywhere which requires a package name, use this default name.
static final String DEFAULT_NAME = ""; static final String DEFAULT_NAME = "";
// As it's a UID-based tracker, while the state change event it receives could be
// in the combination of UID + package name, we'd have to leverage each package's state.
@GuardedBy("mLock")
private UidProcessMap<Integer> mUidPackageStates = new UidProcessMap<>();
AppBatteryExemptionTracker(Context context, AppRestrictionController controller) { AppBatteryExemptionTracker(Context context, AppRestrictionController controller) {
this(context, controller, null, null); this(context, controller, null, null);
} }
@@ -103,12 +111,75 @@ final class AppBatteryExemptionTracker
.getUidBatteryUsage(uid); .getUidBatteryUsage(uid);
final int stateTypeIndex = stateTypeToIndex(stateType); final int stateTypeIndex = stateTypeToIndex(stateType);
synchronized (mLock) { synchronized (mLock) {
UidBatteryStates pkg = mPkgEvents.get(uid, DEFAULT_NAME); final SparseArray<ArrayMap<String, Integer>> map = mUidPackageStates.getMap();
if (pkg == null) { ArrayMap<String, Integer> pkgsStates = map.get(uid);
pkg = createAppStateEvents(uid, DEFAULT_NAME); if (pkgsStates == null) {
mPkgEvents.put(uid, DEFAULT_NAME, pkg); pkgsStates = new ArrayMap<>();
map.put(uid, pkgsStates);
} }
pkg.addEvent(start, now, batteryUsage, stateTypeIndex); int states = 0;
int indexOfPkg = pkgsStates.indexOfKey(packageName);
if (indexOfPkg >= 0) {
states = pkgsStates.valueAt(indexOfPkg);
} else {
pkgsStates.put(packageName, 0);
indexOfPkg = pkgsStates.indexOfKey(packageName);
}
boolean addEvent = false;
if (start) {
// Check if there is another package within this UID with this type of event start.
boolean alreadyStarted = false;
for (int i = pkgsStates.size() - 1; i >= 0; i--) {
final int s = pkgsStates.valueAt(i);
if ((s & stateType) != 0) {
alreadyStarted = true;
break;
}
}
pkgsStates.setValueAt(indexOfPkg, states | stateType);
if (!alreadyStarted) {
// This is the first package within this UID with this type of event start.
addEvent = true;
}
} else {
states &= ~stateType;
pkgsStates.setValueAt(indexOfPkg, states);
boolean allStopped = true;
for (int i = pkgsStates.size() - 1; i >= 0; i--) {
final int s = pkgsStates.valueAt(i);
if ((s & stateType) != 0) {
allStopped = false;
break;
}
}
if (allStopped) {
// None of the packages in this UID has an active event of this type.
addEvent = true;
}
if (states == 0) { // None of the states of this package are active, prune it.
pkgsStates.removeAt(indexOfPkg);
if (pkgsStates.size() == 0) {
map.remove(uid);
}
}
}
if (addEvent) {
UidBatteryStates pkg = mPkgEvents.get(uid, DEFAULT_NAME);
if (pkg == null) {
pkg = createAppStateEvents(uid, DEFAULT_NAME);
mPkgEvents.put(uid, DEFAULT_NAME, pkg);
}
pkg.addEvent(start, now, batteryUsage, stateTypeIndex);
}
}
}
@VisibleForTesting
@Override
void reset() {
super.reset();
synchronized (mLock) {
mUidPackageStates.clear();
} }
} }
@@ -116,6 +187,7 @@ final class AppBatteryExemptionTracker
if (!enabled) { if (!enabled) {
synchronized (mLock) { synchronized (mLock) {
mPkgEvents.clear(); mPkgEvents.clear();
mUidPackageStates.clear();
} }
} }
} }