• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.tare;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.List;
26 
27 /**
28  * Interface for the system server to deal with the resource economy subsystem.
29  *
30  * @hide
31  */
32 public interface EconomyManagerInternal {
33     /**
34      * Used to indicate a future action an app is expected to take.
35      */
36     final class AnticipatedAction {
37         public final int actionId;
38         public final int numInstantaneousCalls;
39         public final long ongoingDurationMs;
40         private final int mHashCode;
41 
42         /**
43          * @param actionId              The expected action
44          * @param numInstantaneousCalls How many instantaneous times the action will be performed
45          * @param ongoingDurationMs     An estimate of how long the ongoing event will go on for
46          */
AnticipatedAction(@conomicPolicy.AppAction int actionId, int numInstantaneousCalls, long ongoingDurationMs)47         public AnticipatedAction(@EconomicPolicy.AppAction int actionId,
48                 int numInstantaneousCalls, long ongoingDurationMs) {
49             this.actionId = actionId;
50             this.numInstantaneousCalls = numInstantaneousCalls;
51             this.ongoingDurationMs = ongoingDurationMs;
52 
53             int hash = 0;
54             hash = 31 * hash + actionId;
55             hash = 31 * hash + numInstantaneousCalls;
56             hash = 31 * hash + (int) (ongoingDurationMs ^ (ongoingDurationMs >>> 32));
57             mHashCode = hash;
58         }
59 
60         @Override
equals(Object o)61         public boolean equals(Object o) {
62             if (this == o) return true;
63             if (o == null || getClass() != o.getClass()) return false;
64             AnticipatedAction that = (AnticipatedAction) o;
65             return actionId == that.actionId
66                     && numInstantaneousCalls == that.numInstantaneousCalls
67                     && ongoingDurationMs == that.ongoingDurationMs;
68         }
69 
70         @Override
hashCode()71         public int hashCode() {
72             return mHashCode;
73         }
74     }
75 
76     /**
77      * A collection of {@link AnticipatedAction AnticipatedActions} that will be performed together.
78      */
79     final class ActionBill {
80         private static final Comparator<AnticipatedAction>
81                 sAnticipatedActionComparator = Comparator.comparingInt(aa -> aa.actionId);
82 
83         private final List<AnticipatedAction> mAnticipatedActions;
84         private final int mHashCode;
85 
ActionBill(@onNull List<AnticipatedAction> anticipatedActions)86         public ActionBill(@NonNull List<AnticipatedAction> anticipatedActions) {
87             List<AnticipatedAction> actions = new ArrayList<>(anticipatedActions);
88             actions.sort(sAnticipatedActionComparator);
89             mAnticipatedActions = Collections.unmodifiableList(actions);
90 
91             int hash = 0;
92             for (int i = 0; i < mAnticipatedActions.size(); ++i) {
93                 hash = 31 * hash + mAnticipatedActions.get(i).hashCode();
94             }
95             mHashCode = hash;
96         }
97 
getAnticipatedActions()98         List<AnticipatedAction> getAnticipatedActions() {
99             return mAnticipatedActions;
100         }
101 
102         @Override
equals(Object o)103         public boolean equals(Object o) {
104             if (this == o) return true;
105             if (o == null || getClass() != o.getClass()) return false;
106             ActionBill that = (ActionBill) o;
107             return mAnticipatedActions.equals(that.mAnticipatedActions);
108         }
109 
110         @Override
hashCode()111         public int hashCode() {
112             return mHashCode;
113         }
114     }
115 
116     /** Listener for when an app's ability to afford a bill changes. */
117     interface AffordabilityChangeListener {
onAffordabilityChanged(int userId, @NonNull String pkgName, @NonNull ActionBill bill, boolean canAfford)118         void onAffordabilityChanged(int userId, @NonNull String pkgName, @NonNull ActionBill bill,
119                 boolean canAfford);
120     }
121 
122     /** Listener for various TARE state changes. */
123     interface TareStateChangeListener {
onTareEnabledStateChanged(boolean isTareEnabled)124         void onTareEnabledStateChanged(boolean isTareEnabled);
125     }
126 
127     /**
128      * Return {@code true} if the app is able to pay for the anticipated actions.
129      */
canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill)130     boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill);
131 
132     /**
133      * Returns the maximum duration (in milliseconds) that the specified app can afford the bill,
134      * based on current prices.
135      */
getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill)136     long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill);
137 
138     /** Returns true if TARE is enabled. */
isEnabled()139     boolean isEnabled();
140 
141     /**
142      * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the
143      * indicated bill changes.
144      */
registerAffordabilityChangeListener(int userId, @NonNull String pkgName, @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill)145     void registerAffordabilityChangeListener(int userId, @NonNull String pkgName,
146             @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill);
147 
148     /**
149      * Unregister a {@link AffordabilityChangeListener} from being notified of any changes to an
150      * app's ability to afford the specified bill.
151      */
unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName, @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill)152     void unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName,
153             @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill);
154 
155     /**
156      * Register a {@link TareStateChangeListener} to track when TARE's state changes.
157      */
registerTareStateChangeListener(@onNull TareStateChangeListener listener)158     void registerTareStateChangeListener(@NonNull TareStateChangeListener listener);
159 
160     /**
161      * Unregister a {@link TareStateChangeListener} from being notified when TARE's state changes.
162      */
unregisterTareStateChangeListener(@onNull TareStateChangeListener listener)163     void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener);
164 
165     /**
166      * Note that an instantaneous event has occurred. The event must be specified in one of the
167      * EconomicPolicies.
168      *
169      * @param tag An optional tag that can be used to differentiate the same event for the same app.
170      */
noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)171     void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId,
172             @Nullable String tag);
173 
174     /**
175      * Note that a long-running event is starting. The event must be specified in one of the
176      * EconomicPolicies. You must always call
177      * {@link #noteOngoingEventStopped(int, String, int, String)} to end the event. Ongoing
178      * events will be separated and grouped by event-tag combinations. There must be an equal
179      * number of start() and stop() calls for the same event-tag combination in order for the
180      * tracking to finally stop (ie. ongoing events are ref-counted).
181      *
182      * @param tag An optional tag that can be used to differentiate the same event for the same app.
183      */
noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)184     void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId,
185             @Nullable String tag);
186 
187     /**
188      * Note that a long-running event has stopped. The event must be specified in one of the
189      * EconomicPolicies. Ongoing events are separated and grouped by event-tag combinations.
190      * There must be an equal number of start() and stop() calls for the same event-tag combination
191      * in order for the tracking to finally stop (ie. ongoing events are ref-counted).
192      *
193      * @param tag An optional tag that can be used to differentiate the same event for the same app.
194      */
noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)195     void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId,
196             @Nullable String tag);
197 }
198