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

Commit a322aa0b authored by Kweku Adams's avatar Kweku Adams Committed by Android (Google) Code Review
Browse files

Merge "Update state when the config changes."

parents 74bfb078 a1a88e92
Loading
Loading
Loading
Loading
+26 −20
Original line number Diff line number Diff line
@@ -89,7 +89,6 @@ class Agent {
    private static final String ALARM_TAG_LEDGER_CLEANUP = "*tare.ledger_cleanup*";

    private final Object mLock;
    private final CompleteEconomicPolicy mCompleteEconomicPolicy;
    private final Handler mHandler;
    private final InternalResourceService mIrs;

@@ -184,11 +183,9 @@ class Agent {
    private static final int MSG_CLEAN_LEDGER = 1;
    private static final int MSG_SET_ALARMS = 2;

    Agent(@NonNull InternalResourceService irs,
            @NonNull CompleteEconomicPolicy completeEconomicPolicy) {
    Agent(@NonNull InternalResourceService irs) {
        mLock = irs.getLock();
        mIrs = irs;
        mCompleteEconomicPolicy = completeEconomicPolicy;
        mHandler = new AgentHandler(TareHandlerThread.get().getLooper());
        mAppStandbyInternal = LocalServices.getService(AppStandbyInternal.class);
    }
@@ -260,19 +257,19 @@ class Agent {

        final long now = getCurrentTimeMillis();
        final Ledger ledger = getLedgerLocked(userId, pkgName);
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();

        final int eventType = getEventType(eventId);
        switch (eventType) {
            case TYPE_ACTION:
                final long actionCost =
                        mCompleteEconomicPolicy.getCostOfAction(eventId, userId, pkgName);
                final long actionCost = economicPolicy.getCostOfAction(eventId, userId, pkgName);

                recordTransactionLocked(userId, pkgName, ledger,
                        new Ledger.Transaction(now, now, eventId, tag, -actionCost), true);
                break;

            case TYPE_REWARD:
                final EconomicPolicy.Reward reward = mCompleteEconomicPolicy.getReward(eventId);
                final EconomicPolicy.Reward reward = economicPolicy.getReward(eventId);
                if (reward != null) {
                    final long rewardSum = ledger.get24HourSum(eventId, now);
                    final long rewardVal = Math.max(0,
@@ -311,11 +308,11 @@ class Agent {
        }
        OngoingEvent ongoingEvent = ongoingEvents.get(eventId, tag);

        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final int eventType = getEventType(eventId);
        switch (eventType) {
            case TYPE_ACTION:
                final long actionCost =
                        mCompleteEconomicPolicy.getCostOfAction(eventId, userId, pkgName);
                final long actionCost = economicPolicy.getCostOfAction(eventId, userId, pkgName);

                if (ongoingEvent == null) {
                    ongoingEvents.add(eventId, tag,
@@ -326,7 +323,7 @@ class Agent {
                break;

            case TYPE_REWARD:
                final EconomicPolicy.Reward reward = mCompleteEconomicPolicy.getReward(eventId);
                final EconomicPolicy.Reward reward = economicPolicy.getReward(eventId);
                if (reward != null) {
                    if (ongoingEvent == null) {
                        ongoingEvents.add(eventId, tag, new OngoingEvent(
@@ -348,8 +345,14 @@ class Agent {

    @GuardedBy("mLock")
    void onDeviceStateChangedLocked() {
        onPricingChangedLocked();
    }

    @GuardedBy("mLock")
    void onPricingChangedLocked() {
        final long now = getCurrentTimeMillis();
        final long nowElapsed = SystemClock.elapsedRealtime();
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();

        mCurrentOngoingEvents.forEach((userId, pkgName, ongoingEvents) -> {
            final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
@@ -381,7 +384,7 @@ class Agent {
                final int size = actionAffordabilityNotes.size();
                for (int i = 0; i < size; ++i) {
                    final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(i);
                    note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName);
                    note.recalculateModifiedPrice(economicPolicy, userId, pkgName);
                    final long newBalance = getLedgerLocked(userId, pkgName).getCurrentBalance();
                    final boolean isAffordable = newBalance >= note.getCachedModifiedPrice();
                    if (wasAffordable[i] != isAffordable) {
@@ -398,6 +401,7 @@ class Agent {
    void onAppStatesChangedLocked(final int userId, @NonNull ArraySet<String> pkgNames) {
        final long now = getCurrentTimeMillis();
        final long nowElapsed = SystemClock.elapsedRealtime();
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();

        for (int i = 0; i < pkgNames.size(); ++i) {
            final String pkgName = pkgNames.valueAt(i);
@@ -433,7 +437,7 @@ class Agent {
                    final int size = actionAffordabilityNotes.size();
                    for (int n = 0; n < size; ++n) {
                        final ActionAffordabilityNote note = actionAffordabilityNotes.valueAt(n);
                        note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName);
                        note.recalculateModifiedPrice(economicPolicy, userId, pkgName);
                        final long newBalance =
                                getLedgerLocked(userId, pkgName).getCurrentBalance();
                        final boolean isAffordable = newBalance >= note.getCachedModifiedPrice();
@@ -532,6 +536,7 @@ class Agent {
                    "Tried to adjust system balance for " + appToString(userId, pkgName));
            return;
        }
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final long maxCirculationAllowed = mIrs.getMaxCirculationLocked();
        final long newArcsInCirculation = mCurrentNarcsInCirculation + transaction.delta;
        if (transaction.delta > 0 && newArcsInCirculation > maxCirculationAllowed) {
@@ -549,12 +554,11 @@ class Agent {
        }
        final long originalBalance = ledger.getCurrentBalance();
        if (transaction.delta > 0
                && originalBalance + transaction.delta
                > mCompleteEconomicPolicy.getMaxSatiatedBalance()) {
                && originalBalance + transaction.delta > economicPolicy.getMaxSatiatedBalance()) {
            // Set lower bound at 0 so we don't accidentally take away credits when we were trying
            // to _give_ the app credits.
            final long newDelta =
                    Math.max(0, mCompleteEconomicPolicy.getMaxSatiatedBalance() - originalBalance);
                    Math.max(0, economicPolicy.getMaxSatiatedBalance() - originalBalance);
            Slog.i(TAG, "Would result in becoming too rich. Decreasing transaction "
                    + eventToString(transaction.eventId)
                    + (transaction.tag == null ? "" : ":" + transaction.tag)
@@ -601,6 +605,7 @@ class Agent {
     */
    @GuardedBy("mLock")
    void reclaimUnusedAssetsLocked(double percentage) {
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final List<PackageInfo> pkgs = mIrs.getInstalledPackages();
        final long now = getCurrentTimeMillis();
        for (int i = 0; i < pkgs.size(); ++i) {
@@ -613,8 +618,7 @@ class Agent {
                    mAppStandbyInternal.getTimeSinceLastUsedByUser(pkgName, userId);
            if (timeSinceLastUsedMs >= MIN_UNUSED_TIME_MS) {
                // Use a constant floor instead of the scaled floor from the IRS.
                final long minBalance =
                        mCompleteEconomicPolicy.getMinSatiatedBalance(userId, pkgName);
                final long minBalance = economicPolicy.getMinSatiatedBalance(userId, pkgName);
                final long curBalance = ledger.getCurrentBalance();
                long toReclaim = (long) (curBalance * percentage);
                if (curBalance - toReclaim < minBalance) {
@@ -1198,8 +1202,9 @@ class Agent {
            actionAffordabilityNotes = new ArraySet<>();
            mActionAffordabilityNotes.add(userId, pkgName, actionAffordabilityNotes);
        }
        final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
        final ActionAffordabilityNote note =
                new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy);
                new ActionAffordabilityNote(bill, listener, economicPolicy);
        if (actionAffordabilityNotes.add(note)) {
            if (!mIrs.isEnabled()) {
                // When TARE isn't enabled, we always say something is affordable. We also don't
@@ -1208,7 +1213,7 @@ class Agent {
                note.setNewAffordability(true);
                return;
            }
            note.recalculateModifiedPrice(mCompleteEconomicPolicy, userId, pkgName);
            note.recalculateModifiedPrice(economicPolicy, userId, pkgName);
            note.setNewAffordability(
                    getBalanceLocked(userId, pkgName) >= note.getCachedModifiedPrice());
            mIrs.postAffordabilityChanged(userId, pkgName, note);
@@ -1224,8 +1229,9 @@ class Agent {
        final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
                mActionAffordabilityNotes.get(userId, pkgName);
        if (actionAffordabilityNotes != null) {
            final CompleteEconomicPolicy economicPolicy = mIrs.getCompleteEconomicPolicyLocked();
            final ActionAffordabilityNote note =
                    new ActionAffordabilityNote(bill, listener, mCompleteEconomicPolicy);
                    new ActionAffordabilityNote(bill, listener, economicPolicy);
            if (actionAffordabilityNotes.remove(note)) {
                // Update ongoing alarm
                scheduleBalanceCheckLocked(userId, pkgName);
+4 −27
Original line number Diff line number Diff line
@@ -98,12 +98,9 @@ import static com.android.server.tare.TareUtils.arcToNarc;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.IndentingPrintWriter;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;

@@ -145,7 +142,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
    private long mMaxSatiatedCirculation;

    private final KeyValueListParser mParser = new KeyValueListParser(',');
    private final SettingsObserver mSettingsObserver;
    private final InternalResourceService mInternalResourceService;

    private final SparseArray<Action> mActions = new SparseArray<>();
@@ -154,7 +150,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
    AlarmManagerEconomicPolicy(InternalResourceService irs) {
        super(irs);
        mInternalResourceService = irs;
        mSettingsObserver = new SettingsObserver(TareHandlerThread.getHandler());
        loadConstants("");
    }

@@ -162,12 +157,7 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
    void setup() {
        super.setup();
        ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
        resolver.registerContentObserver(
                Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS),
                false, mSettingsObserver, UserHandle.USER_ALL);
        loadConstants(Settings.Global.getString(
                mInternalResourceService.getContext().getContentResolver(),
                TARE_ALARM_MANAGER_CONSTANTS));
        loadConstants(Settings.Global.getString(resolver, TARE_ALARM_MANAGER_CONSTANTS));
    }

    @Override
@@ -350,19 +340,6 @@ public class AlarmManagerEconomicPolicy extends EconomicPolicy {
                                DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX))));
    }

    private final class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            loadConstants(Settings.Global.getString(
                    mInternalResourceService.getContext().getContentResolver(),
                    TARE_ALARM_MANAGER_CONSTANTS));
        }
    }

    @Override
    void dump(IndentingPrintWriter pw) {
        pw.println("Actions:");
+6 −6
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ public class CompleteEconomicPolicy extends EconomicPolicy {
    }

    @Override
    public long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
    long getMinSatiatedBalance(final int userId, @NonNull final String pkgName) {
        long min = 0;
        for (int i = 0; i < mEnabledEconomicPolicies.size(); ++i) {
            min += mEnabledEconomicPolicies.valueAt(i).getMinSatiatedBalance(userId, pkgName);
@@ -84,24 +84,24 @@ public class CompleteEconomicPolicy extends EconomicPolicy {
    }

    @Override
    public long getMaxSatiatedBalance() {
    long getMaxSatiatedBalance() {
        return mMaxSatiatedBalance;
    }

    @Override
    public long getMaxSatiatedCirculation() {
     long getMaxSatiatedCirculation() {
        return mMaxSatiatedCirculation;
    }

    @NonNull
    @Override
    public int[] getCostModifiers() {
    int[] getCostModifiers() {
        return mCostModifiers == null ? EmptyArray.INT : mCostModifiers;
    }

    @Nullable
    @Override
    public Action getAction(@AppAction int actionId) {
    Action getAction(@AppAction int actionId) {
        if (mActions.contains(actionId)) {
            return mActions.get(actionId);
        }
@@ -123,7 +123,7 @@ public class CompleteEconomicPolicy extends EconomicPolicy {

    @Nullable
    @Override
    public Reward getReward(@UtilityReward int rewardId) {
    Reward getReward(@UtilityReward int rewardId) {
        if (mRewards.contains(rewardId)) {
            return mRewards.get(rewardId);
        }
+52 −22
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.server.tare;

import static android.provider.Settings.Global.TARE_ALARM_MANAGER_CONSTANTS;
import static android.provider.Settings.Global.TARE_JOB_SCHEDULER_CONSTANTS;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;

@@ -98,11 +100,13 @@ public class InternalResourceService extends SystemService {
    private final PackageManagerInternal mPackageManagerInternal;

    private final Agent mAgent;
    private final CompleteEconomicPolicy mCompleteEconomicPolicy;
    private final ConfigObserver mConfigObserver;
    private final EconomyManagerStub mEconomyManagerStub;
    private final Scribe mScribe;

    @GuardedBy("mLock")
    private CompleteEconomicPolicy mCompleteEconomicPolicy;

    @NonNull
    @GuardedBy("mLock")
    private List<PackageInfo> mPkgCache = new ArrayList<>();
@@ -218,7 +222,7 @@ public class InternalResourceService extends SystemService {
        mEconomyManagerStub = new EconomyManagerStub();
        mScribe = new Scribe(this);
        mCompleteEconomicPolicy = new CompleteEconomicPolicy(this);
        mAgent = new Agent(this, mCompleteEconomicPolicy);
        mAgent = new Agent(this);

        mConfigObserver = new ConfigObserver(mHandler, context);

@@ -246,6 +250,12 @@ public class InternalResourceService extends SystemService {
    }

    /** Returns the installed packages for all users. */
    @NonNull
    @GuardedBy("mLock")
    CompleteEconomicPolicy getCompleteEconomicPolicyLocked() {
        return mCompleteEconomicPolicy;
    }

    @NonNull
    List<PackageInfo> getInstalledPackages() {
        synchronized (mLock) {
@@ -700,14 +710,14 @@ public class InternalResourceService extends SystemService {
            long requiredBalance = 0;
            final List<EconomyManagerInternal.AnticipatedAction> projectedActions =
                    bill.getAnticipatedActions();
            synchronized (mLock) {
                for (int i = 0; i < projectedActions.size(); ++i) {
                    AnticipatedAction action = projectedActions.get(i);
                final long cost =
                        mCompleteEconomicPolicy.getCostOfAction(action.actionId, userId, pkgName);
                    final long cost = mCompleteEconomicPolicy.getCostOfAction(
                            action.actionId, userId, pkgName);
                    requiredBalance += cost * action.numInstantaneousCalls
                            + cost * (action.ongoingDurationMs / 1000);
                }
            synchronized (mLock) {
                return mAgent.getBalanceLocked(userId, pkgName) >= requiredBalance;
            }
        }
@@ -724,16 +734,16 @@ public class InternalResourceService extends SystemService {
            long totalCostPerSecond = 0;
            final List<EconomyManagerInternal.AnticipatedAction> projectedActions =
                    bill.getAnticipatedActions();
            synchronized (mLock) {
                for (int i = 0; i < projectedActions.size(); ++i) {
                    AnticipatedAction action = projectedActions.get(i);
                final long cost =
                        mCompleteEconomicPolicy.getCostOfAction(action.actionId, userId, pkgName);
                    final long cost = mCompleteEconomicPolicy.getCostOfAction(
                            action.actionId, userId, pkgName);
                    totalCostPerSecond += cost;
                }
                if (totalCostPerSecond == 0) {
                    return FOREVER_MS;
                }
            synchronized (mLock) {
                return mAgent.getBalanceLocked(userId, pkgName) * 1000 / totalCostPerSecond;
            }
        }
@@ -786,15 +796,24 @@ public class InternalResourceService extends SystemService {
        public void start() {
            mContentResolver.registerContentObserver(
                    Settings.Global.getUriFor(Settings.Global.ENABLE_TARE), false, this);
            updateConfig();
            mContentResolver.registerContentObserver(
                    Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS), false, this);
            mContentResolver.registerContentObserver(
                    Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS), false, this);
            updateEnabledStatus();
        }

        @Override
        public void onChange(boolean selfChange) {
            updateConfig();
        public void onChange(boolean selfChange, Uri uri) {
            if (uri.equals(Settings.Global.getUriFor(Settings.Global.ENABLE_TARE))) {
                updateEnabledStatus();
            } else if (uri.equals(Settings.Global.getUriFor(TARE_ALARM_MANAGER_CONSTANTS))
                    || uri.equals(Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS))) {
                updateEconomicPolicy();
            }
        }

        private void updateConfig() {
        private void updateEnabledStatus() {
            final boolean isTareEnabled = Settings.Global.getInt(mContentResolver,
                    Settings.Global.ENABLE_TARE, Settings.Global.DEFAULT_ENABLE_TARE) == 1;
            if (mIsEnabled != isTareEnabled) {
@@ -806,6 +825,17 @@ public class InternalResourceService extends SystemService {
                }
            }
        }

        private void updateEconomicPolicy() {
            synchronized (mLock) {
                mCompleteEconomicPolicy.tearDown();
                mCompleteEconomicPolicy = new CompleteEconomicPolicy(InternalResourceService.this);
                if (mIsEnabled && mBootPhase >= PHASE_SYSTEM_SERVICES_READY) {
                    mCompleteEconomicPolicy.setup();
                    mAgent.onPricingChangedLocked();
                }
            }
        }
    }

    private static void dumpHelp(PrintWriter pw) {
+2 −25
Original line number Diff line number Diff line
@@ -107,12 +107,9 @@ import static com.android.server.tare.TareUtils.arcToNarc;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.IndentingPrintWriter;
import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;

@@ -147,7 +144,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
    private long mMaxSatiatedCirculation;

    private final KeyValueListParser mParser = new KeyValueListParser(',');
    private final SettingsObserver mSettingsObserver;
    private final InternalResourceService mInternalResourceService;

    private final SparseArray<Action> mActions = new SparseArray<>();
@@ -156,7 +152,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
    JobSchedulerEconomicPolicy(InternalResourceService irs) {
        super(irs);
        mInternalResourceService = irs;
        mSettingsObserver = new SettingsObserver(TareHandlerThread.getHandler());
        loadConstants("");
    }

@@ -164,12 +159,7 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
    void setup() {
        super.setup();
        ContentResolver resolver = mInternalResourceService.getContext().getContentResolver();
        resolver.registerContentObserver(
                Settings.Global.getUriFor(TARE_JOB_SCHEDULER_CONSTANTS),
                false, mSettingsObserver, UserHandle.USER_ALL);
        loadConstants(Settings.Global.getString(
                mInternalResourceService.getContext().getContentResolver(),
                TARE_JOB_SCHEDULER_CONSTANTS));
        loadConstants(Settings.Global.getString(resolver, TARE_JOB_SCHEDULER_CONSTANTS));
    }

    @Override
@@ -324,19 +314,6 @@ public class JobSchedulerEconomicPolicy extends EconomicPolicy {
                                DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX))));
    }

    private final class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
            super(handler);
        }

        @Override
        public void onChange(boolean selfChange) {
            loadConstants(Settings.Global.getString(
                    mInternalResourceService.getContext().getContentResolver(),
                    TARE_JOB_SCHEDULER_CONSTANTS));
        }
    }

    @Override
    void dump(IndentingPrintWriter pw) {
        pw.println("Actions:");
Loading