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

Commit 5edec9d6 authored by Jing Ji's avatar Jing Ji Committed by Android (Google) Code Review
Browse files

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

parents a6081282 31b9785e
Loading
Loading
Loading
Loading
+77 −5
Original line number Diff line number Diff line
@@ -26,10 +26,13 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.am.AppBatteryExemptionTracker.AppBatteryExemptionPolicy;
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.
    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) {
        this(context, controller, null, null);
    }
@@ -103,6 +111,59 @@ final class AppBatteryExemptionTracker
                .getUidBatteryUsage(uid);
        final int stateTypeIndex = stateTypeToIndex(stateType);
        synchronized (mLock) {
            final SparseArray<ArrayMap<String, Integer>> map = mUidPackageStates.getMap();
            ArrayMap<String, Integer> pkgsStates = map.get(uid);
            if (pkgsStates == null) {
                pkgsStates = new ArrayMap<>();
                map.put(uid, pkgsStates);
            }
            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);
@@ -111,11 +172,22 @@ final class AppBatteryExemptionTracker
                pkg.addEvent(start, now, batteryUsage, stateTypeIndex);
            }
        }
    }

    @VisibleForTesting
    @Override
    void reset() {
        super.reset();
        synchronized (mLock) {
            mUidPackageStates.clear();
        }
    }

    private void onTrackerEnabled(boolean enabled) {
        if (!enabled) {
            synchronized (mLock) {
                mPkgEvents.clear();
                mUidPackageStates.clear();
            }
        }
    }