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

Commit 9bf45ccf authored by Kweku Adams's avatar Kweku Adams
Browse files

Add shell command so tests aren't hindered.

Add a shell command that allows tests to temporarily exempt themselves
from all TARE policy.

Bug: 242294488
Test: set battery level to 10%, unplug, then:
Test: atest --rerun-until-failure 100 CtsOsTestCases:AppHibernationIntegrationTest
Test: atest --rerun-until-failure 100 CtsOsTestCases:AutoRevokeTest
Test: atest --rerun-until-failure 100 CtsPermissionTestCases:NotificationListenerCheckTest
Test: atest --rerun-until-failure 100 CtsPermissionTestCases:LocationAccessCheckTest
Test: atest frameworks/base/services/tests/mockingservicestests/src/com/android/server/tare
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/tare
Change-Id: I95f3c2ad27c603c94784d13d5c75db4e58ade974
parent e56def66
Loading
Loading
Loading
Loading
+69 −10
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Log;
import android.util.Slog;
import android.util.Slog;
import android.util.SparseArrayMap;
import android.util.SparseArrayMap;
import android.util.SparseSetArray;
import android.util.TimeUtils;
import android.util.TimeUtils;


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


        for (int i = 0; i < pkgNames.size(); ++i) {
        for (int i = 0; i < pkgNames.size(); ++i) {
            final String pkgName = pkgNames.valueAt(i);
            final String pkgName = pkgNames.valueAt(i);
            final boolean isVip = mIrs.isVip(userId, pkgName);
            SparseArrayMap<String, OngoingEvent> ongoingEvents =
            SparseArrayMap<String, OngoingEvent> ongoingEvents =
                    mCurrentOngoingEvents.get(userId, pkgName);
                    mCurrentOngoingEvents.get(userId, pkgName);
            if (ongoingEvents != null) {
            if (ongoingEvents != null) {
@@ -296,8 +298,8 @@ class Agent {
                    for (int n = 0; n < size; ++n) {
                    for (int n = 0; n < size; ++n) {
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        final boolean isAffordable =
                        final boolean isAffordable = isVip
                                isAffordableLocked(newBalance,
                                || isAffordableLocked(newBalance,
                                        note.getCachedModifiedPrice(), note.getCtp());
                                        note.getCachedModifiedPrice(), note.getCtp());
                        if (note.isCurrentlyAffordable() != isAffordable) {
                        if (note.isCurrentlyAffordable() != isAffordable) {
                            note.setNewAffordability(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")
    @GuardedBy("mLock")
    private void onAnythingChangedLocked(final boolean updateOngoingEvents) {
    private void onAnythingChangedLocked(final boolean updateOngoingEvents) {
        final long now = getCurrentTimeMillis();
        final long now = getCurrentTimeMillis();
@@ -347,11 +394,12 @@ class Agent {
                if (actionAffordabilityNotes != null) {
                if (actionAffordabilityNotes != null) {
                    final int size = actionAffordabilityNotes.size();
                    final int size = actionAffordabilityNotes.size();
                    final long newBalance = getBalanceLocked(userId, pkgName);
                    final long newBalance = getBalanceLocked(userId, pkgName);
                    final boolean isVip = mIrs.isVip(userId, pkgName);
                    for (int n = 0; n < size; ++n) {
                    for (int n = 0; n < size; ++n) {
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        note.recalculateCosts(economicPolicy, userId, pkgName);
                        final boolean isAffordable =
                        final boolean isAffordable = isVip
                                isAffordableLocked(newBalance,
                                || isAffordableLocked(newBalance,
                                        note.getCachedModifiedPrice(), note.getCtp());
                                        note.getCachedModifiedPrice(), note.getCtp());
                        if (note.isCurrentlyAffordable() != isAffordable) {
                        if (note.isCurrentlyAffordable() != isAffordable) {
                            note.setNewAffordability(isAffordable);
                            note.setNewAffordability(isAffordable);
@@ -452,6 +500,14 @@ class Agent {
                    "Tried to adjust system balance for " + appToString(userId, pkgName));
                    "Tried to adjust system balance for " + appToString(userId, pkgName));
            return;
            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 CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final long originalBalance = ledger.getCurrentBalance();
        final long originalBalance = ledger.getCurrentBalance();
        if (transaction.delta > 0
        if (transaction.delta > 0
@@ -477,10 +533,11 @@ class Agent {
                    mActionAffordabilityNotes.get(userId, pkgName);
                    mActionAffordabilityNotes.get(userId, pkgName);
            if (actionAffordabilityNotes != null) {
            if (actionAffordabilityNotes != null) {
                final long newBalance = ledger.getCurrentBalance();
                final long newBalance = ledger.getCurrentBalance();
                final boolean isVip = mIrs.isVip(userId, pkgName);
                for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
                for (int i = 0; i < actionAffordabilityNotes.size(); ++i) {
                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
                    final boolean isAffordable =
                    final boolean isAffordable = isVip
                            isAffordableLocked(newBalance,
                            || isAffordableLocked(newBalance,
                                    note.getCachedModifiedPrice(), note.getCtp());
                                    note.getCachedModifiedPrice(), note.getCtp());
                    if (note.isCurrentlyAffordable() != isAffordable) {
                    if (note.isCurrentlyAffordable() != isAffordable) {
                        note.setNewAffordability(isAffordable);
                        note.setNewAffordability(isAffordable);
@@ -866,7 +923,7 @@ class Agent {
    private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) {
    private void scheduleBalanceCheckLocked(final int userId, @NonNull final String pkgName) {
        SparseArrayMap<String, OngoingEvent> ongoingEvents =
        SparseArrayMap<String, OngoingEvent> ongoingEvents =
                mCurrentOngoingEvents.get(userId, pkgName);
                mCurrentOngoingEvents.get(userId, pkgName);
        if (ongoingEvents == null) {
        if (ongoingEvents == null || mIrs.isVip(userId, pkgName)) {
            // No ongoing transactions. No reason to schedule
            // No ongoing transactions. No reason to schedule
            mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName));
            mBalanceThresholdAlarmQueue.removeAlarmForKey(new Package(userId, pkgName));
            return;
            return;
@@ -1059,9 +1116,10 @@ class Agent {
                note.setNewAffordability(true);
                note.setNewAffordability(true);
                return;
                return;
            }
            }
            final boolean isVip = mIrs.isVip(userId, pkgName);
            note.recalculateCosts(economicPolicy, userId, pkgName);
            note.recalculateCosts(economicPolicy, userId, pkgName);
            note.setNewAffordability(
            note.setNewAffordability(isVip
                    isAffordableLocked(getBalanceLocked(userId, pkgName),
                    || isAffordableLocked(getBalanceLocked(userId, pkgName),
                            note.getCachedModifiedPrice(), note.getCtp()));
                            note.getCachedModifiedPrice(), note.getCtp()));
            mIrs.postAffordabilityChanged(userId, pkgName, note);
            mIrs.postAffordabilityChanged(userId, pkgName, note);
            // Update ongoing alarm
            // Update ongoing alarm
@@ -1200,11 +1258,12 @@ class Agent {
                        if (actionAffordabilityNotes != null
                        if (actionAffordabilityNotes != null
                                && actionAffordabilityNotes.size() > 0) {
                                && actionAffordabilityNotes.size() > 0) {
                            final long newBalance = getBalanceLocked(userId, pkgName);
                            final long newBalance = getBalanceLocked(userId, pkgName);
                            final boolean isVip = mIrs.isVip(userId, pkgName);


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


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


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


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


    @Override
    @Override
    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
        if (mInternalResourceService.isPackageExempted(userId, pkgName)) {
        if (mIrs.isPackageExempted(userId, pkgName)) {
            return mMinSatiatedBalanceExempted;
            return mMinSatiatedBalanceExempted;
        }
        }
        // TODO: take other exemptions into account
        // TODO: take other exemptions into account
+3 −1
Original line number Original line 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];
    private static final Modifier[] COST_MODIFIER_BY_INDEX = new Modifier[NUM_COST_MODIFIERS];


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


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

    private volatile boolean mIsEnabled;
    private volatile boolean mIsEnabled;
    private volatile int mBootPhase;
    private volatile int mBootPhase;
    private volatile boolean mExemptListLoaded;
    private volatile boolean mExemptListLoaded;
@@ -368,6 +372,21 @@ public class InternalResourceService extends SystemService {
        return UserHandle.isCore(getUid(userId, pkgName));
        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() {
    void onBatteryLevelChanged() {
        synchronized (mLock) {
        synchronized (mLock) {
            final int newBatteryLevel = getCurrentBatteryLevel();
            final int newBatteryLevel = getCurrentBatteryLevel();
@@ -470,6 +489,7 @@ public class InternalResourceService extends SystemService {
        }
        }
        synchronized (mLock) {
        synchronized (mLock) {
            mUidToPackageCache.remove(uid, pkgName);
            mUidToPackageCache.remove(uid, pkgName);
            mVipOverrides.delete(userId, pkgName);
            for (int i = 0; i < mPkgCache.size(); ++i) {
            for (int i = 0; i < mPkgCache.size(); ++i) {
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
                if (UserHandle.getUserId(pkgInfo.uid) == userId
                if (UserHandle.getUserId(pkgInfo.uid) == userId
@@ -506,6 +526,7 @@ public class InternalResourceService extends SystemService {


    void onUserRemoved(final int userId) {
    void onUserRemoved(final int userId) {
        synchronized (mLock) {
        synchronized (mLock) {
            mVipOverrides.delete(userId);
            ArrayList<String> removedPkgs = new ArrayList<>();
            ArrayList<String> removedPkgs = new ArrayList<>();
            for (int i = mPkgCache.size() - 1; i >= 0; --i) {
            for (int i = mPkgCache.size() - 1; i >= 0; --i) {
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
                final InstalledPackageInfo pkgInfo = mPkgCache.get(i);
@@ -886,6 +907,15 @@ public class InternalResourceService extends SystemService {
                Binder.restoreCallingIdentity(identityToken);
                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 {
    private final class LocalService implements EconomyManagerInternal {
@@ -937,9 +967,9 @@ public class InternalResourceService extends SystemService {
            if (!mIsEnabled) {
            if (!mIsEnabled) {
                return true;
                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
                // The government, I mean the system, can create ARCs as it needs to in order to
                // operate.
                // allow VIPs to operate.
                return true;
                return true;
            }
            }
            // TODO: take temp-allowlist into consideration
            // TODO: take temp-allowlist into consideration
@@ -965,7 +995,7 @@ public class InternalResourceService extends SystemService {
            if (!mIsEnabled) {
            if (!mIsEnabled) {
                return FOREVER_MS;
                return FOREVER_MS;
            }
            }
            if (isSystem(userId, pkgName)) {
            if (isVip(userId, pkgName)) {
                return FOREVER_MS;
                return FOREVER_MS;
            }
            }
            long totalCostPerSecond = 0;
            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) {
    private static void dumpHelp(PrintWriter pw) {
        pw.println("Resource Economy (economy) dump options:");
        pw.println("Resource Economy (economy) dump options:");
        pw.println("  [-h|--help] [package] ...");
        pw.println("  [-h|--help] [package] ...");
@@ -1173,6 +1244,29 @@ public class InternalResourceService extends SystemService {
            pw.print("Exempted apps", mExemptedApps);
            pw.print("Exempted apps", mExemptedApps);
            pw.println();
            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();
            pw.println();
            mCompleteEconomicPolicy.dump(pw);
            mCompleteEconomicPolicy.dump(pw);


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


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


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


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


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