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

Commit 63979bd5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add shell command so tests aren't hindered."

parents da186feb 9bf45ccf
Loading
Loading
Loading
Loading
+69 −10
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArrayMap;
import android.util.SparseSetArray;
import android.util.TimeUtils;

import com.android.internal.annotations.GuardedBy;
@@ -282,6 +283,7 @@ class Agent {

        for (int i = 0; i < pkgNames.size(); ++i) {
            final String pkgName = pkgNames.valueAt(i);
            final boolean isVip = mIrs.isVip(userId, pkgName);
            SparseArrayMap<String, OngoingEvent> ongoingEvents =
                    mCurrentOngoingEvents.get(userId, pkgName);
            if (ongoingEvents != null) {
@@ -296,8 +298,8 @@ class Agent {
                    for (int n = 0; n < size; ++n) {
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        final boolean isAffordable =
                                isAffordableLocked(newBalance,
                        final boolean isAffordable = isVip
                                || isAffordableLocked(newBalance,
                                        note.getCachedModifiedPrice(), note.getCtp());
                        if (note.isCurrentlyAffordable() != isAffordable) {
                            note.setNewAffordability(isAffordable);
@@ -310,6 +312,51 @@ class Agent {
        }
    }

    @GuardedBy("mLock")
    void onVipStatusChangedLocked(final int userId, @NonNull String pkgName) {
        final long now = getCurrentTimeMillis();
        final long nowElapsed = SystemClock.elapsedRealtime();
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();

        final boolean isVip = mIrs.isVip(userId, pkgName);
        SparseArrayMap<String, OngoingEvent> ongoingEvents =
                mCurrentOngoingEvents.get(userId, pkgName);
        if (ongoingEvents != null) {
            mOngoingEventUpdater.reset(userId, pkgName, now, nowElapsed);
            ongoingEvents.forEach(mOngoingEventUpdater);
        }
        final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
                mActionAffordabilityNotes.get(userId, pkgName);
        if (actionAffordabilityNotes != null) {
            final int size = actionAffordabilityNotes.size();
            final long newBalance =
                    mScribe.getLedgerLocked(userId, pkgName).getCurrentBalance();
            for (int n = 0; n < size; ++n) {
                final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                note.recalculateCosts(economicPolicy, userId, pkgName);
                final boolean isAffordable = isVip
                        || isAffordableLocked(newBalance,
                        note.getCachedModifiedPrice(), note.getCtp());
                if (note.isCurrentlyAffordable() != isAffordable) {
                    note.setNewAffordability(isAffordable);
                    mIrs.postAffordabilityChanged(userId, pkgName, note);
                }
            }
        }
        scheduleBalanceCheckLocked(userId, pkgName);
    }

    @GuardedBy("mLock")
    void onVipStatusChangedLocked(@NonNull SparseSetArray<String> pkgs) {
        for (int u = pkgs.size() - 1; u >= 0; --u) {
            final int userId = pkgs.keyAt(u);

            for (int p = pkgs.sizeAt(u) - 1; p >= 0; --p) {
                onVipStatusChangedLocked(userId, pkgs.valueAt(u, p));
            }
        }
    }

    @GuardedBy("mLock")
    private void onAnythingChangedLocked(final boolean updateOngoingEvents) {
        final long now = getCurrentTimeMillis();
@@ -347,11 +394,12 @@ class Agent {
                if (actionAffordabilityNotes != null) {
                    final int size = actionAffordabilityNotes.size();
                    final long newBalance = getBalanceLocked(userId, pkgName);
                    final boolean isVip = mIrs.isVip(userId, pkgName);
                    for (int n = 0; n < size; ++n) {
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        final boolean isAffordable =
                                isAffordableLocked(newBalance,
                        final boolean isAffordable = isVip
                                || isAffordableLocked(newBalance,
                                        note.getCachedModifiedPrice(), note.getCtp());
                        if (note.isCurrentlyAffordable() != isAffordable) {
                            note.setNewAffordability(isAffordable);
@@ -452,6 +500,14 @@ class Agent {
                    "Tried to adjust system balance for " + appToString(userId, pkgName));
            return;
        }
        if (mIrs.isVip(userId, pkgName)) {
            // This could happen if the app was made a VIP after it started performing actions.
            // Continue recording the transaction for debugging purposes, but don't let it change
            // any numbers.
            transaction = new Ledger.Transaction(
                    transaction.startTimeMs, transaction.endTimeMs,
                    transaction.eventId, transaction.tag, 0 /* delta */, transaction.ctp);
        }
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final long originalBalance = ledger.getCurrentBalance();
        if (transaction.delta > 0
@@ -477,10 +533,11 @@ class Agent {
                    mActionAffordabilityNotes.get(userId, pkgName);
            if (actionAffordabilityNotes != null) {
                final long newBalance = ledger.getCurrentBalance();
                final boolean isVip = mIrs.isVip(userId, pkgName);
                for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
                    final boolean isAffordable =
                            isAffordableLocked(newBalance,
                    final boolean isAffordable = isVip
                            || isAffordableLocked(newBalance,
                                    note.getCachedModifiedPrice(), note.getCtp());
                    if (note.isCurrentlyAffordable() != isAffordable) {
                        note.setNewAffordability(isAffordable);
@@ -866,7 +923,7 @@ class Agent {
    private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) {
        SparseArrayMap<String, OngoingEvent> ongoingEvents =
                mCurrentOngoingEvents.get(userId, pkgName);
        if (ongoingEvents == null) {
        if (ongoingEvents == null || mIrs.isVip(userId, pkgName)) {
            // No ongoing transactions. No reason to schedule
            mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName));
            return;
@@ -1059,9 +1116,10 @@ class Agent {
                note.setNewAffordability(true);
                return;
            }
            final boolean isVip = mIrs.isVip(userId, pkgName);
            note.recalculateCosts(economicPolicy, userId, pkgName);
            note.setNewAffordability(
                    isAffordableLocked(getBalanceLocked(userId, pkgName),
            note.setNewAffordability(isVip
                    || isAffordableLocked(getBalanceLocked(userId, pkgName),
                            note.getCachedModifiedPrice(), note.getCtp()));
            mIrs.postAffordabilityChanged(userId, pkgName, note);
            // Update ongoing alarm
@@ -1200,11 +1258,12 @@ class Agent {
                        if (actionAffordabilityNotes != null
                                && actionAffordabilityNotes.size() > 0) {
                            final long newBalance = getBalanceLocked(userId, pkgName);
                            final boolean isVip = mIrs.isVip(userId, pkgName);

                            for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
                                final ActionAffordabilityNote note =
                                        actionAffordabilityNotes.valueAt(i);
                                final boolean isAffordable = isAffordableLocked(
                                final boolean isAffordable = isVip || isAffordableLocked(
                                        newBalance, note.getCachedModifiedPrice(), note.getCtp());
                                if (note.isCurrentlyAffordable() != isAffordable) {
                                    note.setNewAffordability(isAffordable);
+2 −4
Original line number Diff line number Diff line
@@ -149,7 +149,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
    private long mHardSatiatedConsumptionLimit;

    private final KeyValueListParser mParser = new KeyValueListParser(',');
    private final InternalResourceService mInternalResourceService;
    private final Injector mInjector;

    private final SparseArray<Action> mActions = new SparseArray<>();
@@ -157,7 +156,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {

    AlarmManagerEconomicPolicy(InternalResourceService irs, Injector injector) {
        super(irs);
        mInternalResourceService = irs;
        mInjector = injector;
        loadConstants("", null);
    }
@@ -165,14 +163,14 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
    @Override
    void setup(@NonNull DeviceConfig.Properties properties) {
        super.setup(properties);
        ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
        ContentResolver resolver = mIrs.getContext().getContentResolver();
        loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_ALARM_MANAGER_CONSTANTS),
                properties);
    }

    @Override
    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
        if (mInternalResourceService.isPackageExempted(userId, pkgName)) {
        if (mIrs.isPackageExempted(userId, pkgName)) {
            return mMinSatiatedBalanceExempted;
        }
        // TODO: take other exemptions into account
+3 −1
Original line number Diff line number Diff line
@@ -169,9 +169,11 @@ public abstract class EconomicPolicy {
        }
    }

    protected final InternalResourceService mIrs;
    private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS];

    EconomicPolicy(@NonNull InternalResourceService irs) {
        mIrs = irs;
        for (int mId : getCostModifiers()) {
            initModifier(mId, irs);
        }
@@ -240,7 +242,7 @@ public abstract class EconomicPolicy {
    @NonNull
    final Cost getCostOfAction(int actionId, int userId, @NonNull String pkgName) {
        final Action action = getAction(actionId);
        if (action == null) {
        if (action == null || mIrs.isVip(userId, pkgName)) {
            return new Cost(0, 0);
        }
        long ctp = action.costToProduce;
+97 −3
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ import android.os.Handler;
import android.os.IDeviceIdleController;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -149,6 +150,9 @@ public class InternalResourceService extends SystemService {
    @GuardedBy("mLock")
    private ArraySet<String> mExemptedApps = new ArraySet<>();

    @GuardedBy("mLock")
    private final SparseArrayMap<String, Boolean> mVipOverrides = new SparseArrayMap<>();

    private volatile boolean mIsEnabled;
    private volatile int mBootPhase;
    private volatile boolean mExemptListLoaded;
@@ -368,6 +372,21 @@ public class InternalResourceService extends SystemService {
        return UserHandle.isCore(getUid(userId, pkgName));
    }

    boolean isVip(final int userId, @NonNull String pkgName) {
        synchronized (mLock) {
            final Boolean override = mVipOverrides.get(userId, pkgName);
            if (override != null) {
                return override;
            }
        }
        if (isSystem(userId, pkgName)) {
            // The government, I mean the system, can create ARCs as it needs to in order to
            // operate.
            return true;
        }
        return false;
    }

    void onBatteryLevelChanged() {
        synchronized (mLock) {
            final int newBatteryLevel = getCurrentBatteryLevel();
@@ -470,6 +489,7 @@ public class InternalResourceService extends SystemService {
        }
        synchronized (mLock) {
            mUidToPackageCache.remove(uid, pkgName);
            mVipOverrides.delete(userId, pkgName);
            for (int i = 0; i < mPkgCache.size(); ++i) {
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
                if (UserHandle.getUserId(pkgInfo.uid) == userId
@@ -506,6 +526,7 @@ public class InternalResourceService extends SystemService {

    void onUserRemoved(final int userId) {
        synchronized (mLock) {
            mVipOverrides.delete(userId);
            ArrayList<String> removedPkgs = new ArrayList<>();
            for (int i = mPkgCache.size() - 1; i >= 0; --i) {
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
@@ -886,6 +907,15 @@ public class InternalResourceService extends SystemService {
                Binder.restoreCallingIdentity(identityToken);
            }
        }

        @Override
        public int handleShellCommand(@NonNull ParcelFileDescriptor in,
                @NonNull ParcelFileDescriptor out, @NonNull ParcelFileDescriptor err,
                @NonNull String[] args) {
            return (new TareShellCommand(InternalResourceService.this)).exec(
                    this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(),
                    args);
        }
    }

    private final class LocalService implements EconomyManagerInternal {
@@ -937,9 +967,9 @@ public class InternalResourceService extends SystemService {
            if (!mIsEnabled) {
                return true;
            }
            if (isSystem(userId, pkgName)) {
            if (isVip(userId, pkgName)) {
                // The government, I mean the system, can create ARCs as it needs to in order to
                // operate.
                // allow VIPs to operate.
                return true;
            }
            // TODO: take temp-allowlist into consideration
@@ -965,7 +995,7 @@ public class InternalResourceService extends SystemService {
            if (!mIsEnabled) {
                return FOREVER_MS;
            }
            if (isSystem(userId, pkgName)) {
            if (isVip(userId, pkgName)) {
                return FOREVER_MS;
            }
            long totalCostPerSecond = 0;
@@ -1136,6 +1166,47 @@ public class InternalResourceService extends SystemService {
        }
    }

    // Shell command infrastructure
    int executeClearVip(@NonNull PrintWriter pw) {
        synchronized (mLock) {
            final SparseSetArray<String> changedPkgs = new SparseSetArray<>();
            for (int u = mVipOverrides.numMaps() - 1; u >= 0; --u) {
                final int userId = mVipOverrides.keyAt(u);

                for (int p = mVipOverrides.numElementsForKeyAt(u) - 1; p >= 0; --p) {
                    changedPkgs.add(userId, mVipOverrides.keyAt(u, p));
                }
            }
            mVipOverrides.clear();
            if (mIsEnabled) {
                mAgent.onVipStatusChangedLocked(changedPkgs);
            }
        }
        pw.println("Cleared all VIP statuses");
        return TareShellCommand.COMMAND_SUCCESS;
    }

    int executeSetVip(@NonNull PrintWriter pw,
            int userId, @NonNull String pkgName, @Nullable Boolean newVipState) {
        final boolean changed;
        synchronized (mLock) {
            final boolean wasVip = isVip(userId, pkgName);
            if (newVipState == null) {
                mVipOverrides.delete(userId, pkgName);
            } else {
                mVipOverrides.add(userId, pkgName, newVipState);
            }
            changed = isVip(userId, pkgName) != wasVip;
            if (mIsEnabled && changed) {
                mAgent.onVipStatusChangedLocked(userId, pkgName);
            }
        }
        pw.println(appToString(userId, pkgName) + " VIP status set to " + newVipState + "."
                + " Final VIP state changed? " + changed);
        return TareShellCommand.COMMAND_SUCCESS;
    }

    // Dump infrastructure
    private static void dumpHelp(PrintWriter pw) {
        pw.println("Resource Economy (economy) dump options:");
        pw.println("  [-h|--help] [package] ...");
@@ -1173,6 +1244,29 @@ public class InternalResourceService extends SystemService {
            pw.print("Exempted apps", mExemptedApps);
            pw.println();

            boolean printedVips = false;
            pw.println();
            pw.print("VIPs:");
            for (int u = 0; u < mVipOverrides.numMaps(); ++u) {
                final int userId = mVipOverrides.keyAt(u);

                for (int p = 0; p < mVipOverrides.numElementsForKeyAt(u); ++p) {
                    final String pkgName = mVipOverrides.keyAt(u, p);

                    printedVips = true;
                    pw.println();
                    pw.print(appToString(userId, pkgName));
                    pw.print("=");
                    pw.print(mVipOverrides.valueAt(u, p));
                }
            }
            if (printedVips) {
                pw.println();
            } else {
                pw.print(" None");
            }
            pw.println();

            pw.println();
            mCompleteEconomicPolicy.dump(pw);

+2 −4
Original line number Diff line number Diff line
@@ -151,7 +151,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
    private long mHardSatiatedConsumptionLimit;

    private final KeyValueListParser mParser = new KeyValueListParser(',');
    private final InternalResourceService mInternalResourceService;
    private final Injector mInjector;

    private final SparseArray<Action> mActions = new SparseArray<>();
@@ -159,7 +158,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {

    JobSchedulerEconomicPolicy(InternalResourceService irs, Injector injector) {
        super(irs);
        mInternalResourceService = irs;
        mInjector = injector;
        loadConstants("", null);
    }
@@ -167,14 +165,14 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
    @Override
    void setup(@NonNull DeviceConfig.Properties properties) {
        super.setup(properties);
        ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
        final ContentResolver resolver = mIrs.getContext().getContentResolver();
        loadConstants(mInjector.getSettingsGlobalString(resolver, TARE_JOB_SCHEDULER_CONSTANTS),
                properties);
    }

    @Override
    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
        if (mInternalResourceService.isPackageExempted(userId, pkgName)) {
        if (mIrs.isPackageExempted(userId, pkgName)) {
            return mMinSatiatedBalanceExempted;
        }
        // TODO: take other exemptions into account
Loading