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 import android.app.tare.EconomyManager; 22 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.Comparator; 26 import java.util.List; 27 28 /** 29 * Interface for the system server to deal with the resource economy subsystem. 30 * 31 * @hide 32 */ 33 public interface EconomyManagerInternal { 34 /** 35 * Used to indicate a future action an app is expected to take. 36 */ 37 final class AnticipatedAction { 38 public final int actionId; 39 public final int numInstantaneousCalls; 40 public final long ongoingDurationMs; 41 private final int mHashCode; 42 43 /** 44 * @param actionId The expected action 45 * @param numInstantaneousCalls How many instantaneous times the action will be performed 46 * @param ongoingDurationMs An estimate of how long the ongoing event will go on for 47 */ AnticipatedAction(@conomicPolicy.AppAction int actionId, int numInstantaneousCalls, long ongoingDurationMs)48 public AnticipatedAction(@EconomicPolicy.AppAction int actionId, 49 int numInstantaneousCalls, long ongoingDurationMs) { 50 this.actionId = actionId; 51 this.numInstantaneousCalls = numInstantaneousCalls; 52 this.ongoingDurationMs = ongoingDurationMs; 53 54 int hash = 0; 55 hash = 31 * hash + actionId; 56 hash = 31 * hash + numInstantaneousCalls; 57 hash = 31 * hash + (int) (ongoingDurationMs ^ (ongoingDurationMs >>> 32)); 58 mHashCode = hash; 59 } 60 61 @Override equals(Object o)62 public boolean equals(Object o) { 63 if (this == o) return true; 64 if (o == null || getClass() != o.getClass()) return false; 65 AnticipatedAction that = (AnticipatedAction) o; 66 return actionId == that.actionId 67 && numInstantaneousCalls == that.numInstantaneousCalls 68 && ongoingDurationMs == that.ongoingDurationMs; 69 } 70 71 @Override hashCode()72 public int hashCode() { 73 return mHashCode; 74 } 75 } 76 77 /** 78 * A collection of {@link AnticipatedAction AnticipatedActions} that will be performed together. 79 */ 80 final class ActionBill { 81 private static final Comparator<AnticipatedAction> 82 sAnticipatedActionComparator = Comparator.comparingInt(aa -> aa.actionId); 83 84 private final List<AnticipatedAction> mAnticipatedActions; 85 private final int mHashCode; 86 ActionBill(@onNull List<AnticipatedAction> anticipatedActions)87 public ActionBill(@NonNull List<AnticipatedAction> anticipatedActions) { 88 List<AnticipatedAction> actions = new ArrayList<>(anticipatedActions); 89 actions.sort(sAnticipatedActionComparator); 90 mAnticipatedActions = Collections.unmodifiableList(actions); 91 92 int hash = 0; 93 for (int i = 0; i < mAnticipatedActions.size(); ++i) { 94 hash = 31 * hash + mAnticipatedActions.get(i).hashCode(); 95 } 96 mHashCode = hash; 97 } 98 getAnticipatedActions()99 List<AnticipatedAction> getAnticipatedActions() { 100 return mAnticipatedActions; 101 } 102 103 @Override equals(Object o)104 public boolean equals(Object o) { 105 if (this == o) return true; 106 if (o == null || getClass() != o.getClass()) return false; 107 ActionBill that = (ActionBill) o; 108 return mAnticipatedActions.equals(that.mAnticipatedActions); 109 } 110 111 @Override hashCode()112 public int hashCode() { 113 return mHashCode; 114 } 115 } 116 117 /** Listener for when an app's ability to afford a bill changes. */ 118 interface AffordabilityChangeListener { onAffordabilityChanged(int userId, @NonNull String pkgName, @NonNull ActionBill bill, boolean canAfford)119 void onAffordabilityChanged(int userId, @NonNull String pkgName, @NonNull ActionBill bill, 120 boolean canAfford); 121 } 122 123 /** Listener for various TARE state changes. */ 124 interface TareStateChangeListener { onTareEnabledModeChanged(@conomyManager.EnabledMode int tareEnabledMode)125 void onTareEnabledModeChanged(@EconomyManager.EnabledMode int tareEnabledMode); 126 } 127 128 /** 129 * Return {@code true} if the app is able to pay for the anticipated actions. 130 */ canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill)131 boolean canPayFor(int userId, @NonNull String pkgName, @NonNull ActionBill bill); 132 133 /** 134 * Returns the maximum duration (in milliseconds) that the specified app can afford the bill, 135 * based on current prices. 136 */ getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill)137 long getMaxDurationMs(int userId, @NonNull String pkgName, @NonNull ActionBill bill); 138 139 /** Returns the current TARE enabled mode. */ 140 @EconomyManager.EnabledMode getEnabledMode()141 int getEnabledMode(); 142 143 /** Returns the current TARE enabled mode for the specified policy. */ 144 @EconomyManager.EnabledMode getEnabledMode(@conomicPolicy.Policy int policyId)145 int getEnabledMode(@EconomicPolicy.Policy int policyId); 146 147 /** 148 * Register an {@link AffordabilityChangeListener} to track when an app's ability to afford the 149 * indicated bill changes. 150 */ registerAffordabilityChangeListener(int userId, @NonNull String pkgName, @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill)151 void registerAffordabilityChangeListener(int userId, @NonNull String pkgName, 152 @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill); 153 154 /** 155 * Unregister a {@link AffordabilityChangeListener} from being notified of any changes to an 156 * app's ability to afford the specified bill. 157 */ unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName, @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill)158 void unregisterAffordabilityChangeListener(int userId, @NonNull String pkgName, 159 @NonNull AffordabilityChangeListener listener, @NonNull ActionBill bill); 160 161 /** 162 * Register a {@link TareStateChangeListener} to track when TARE's state changes. 163 */ registerTareStateChangeListener(@onNull TareStateChangeListener listener, @EconomicPolicy.Policy int policyId)164 void registerTareStateChangeListener(@NonNull TareStateChangeListener listener, 165 @EconomicPolicy.Policy int policyId); 166 167 /** 168 * Unregister a {@link TareStateChangeListener} from being notified when TARE's state changes. 169 */ unregisterTareStateChangeListener(@onNull TareStateChangeListener listener)170 void unregisterTareStateChangeListener(@NonNull TareStateChangeListener listener); 171 172 /** 173 * Note that an instantaneous event has occurred. The event must be specified in one of the 174 * EconomicPolicies. 175 * 176 * @param tag An optional tag that can be used to differentiate the same event for the same app. 177 */ noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)178 void noteInstantaneousEvent(int userId, @NonNull String pkgName, int eventId, 179 @Nullable String tag); 180 181 /** 182 * Note that a long-running event is starting. The event must be specified in one of the 183 * EconomicPolicies. You must always call 184 * {@link #noteOngoingEventStopped(int, String, int, String)} to end the event. Ongoing 185 * events will be separated and grouped by event-tag combinations. There must be an equal 186 * number of start() and stop() calls for the same event-tag combination in order for the 187 * tracking to finally stop (ie. ongoing events are ref-counted). 188 * 189 * @param tag An optional tag that can be used to differentiate the same event for the same app. 190 */ noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)191 void noteOngoingEventStarted(int userId, @NonNull String pkgName, int eventId, 192 @Nullable String tag); 193 194 /** 195 * Note that a long-running event has stopped. The event must be specified in one of the 196 * EconomicPolicies. Ongoing events are separated and grouped by event-tag combinations. 197 * There must be an equal number of start() and stop() calls for the same event-tag combination 198 * in order for the tracking to finally stop (ie. ongoing events are ref-counted). 199 * 200 * @param tag An optional tag that can be used to differentiate the same event for the same app. 201 */ noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, @Nullable String tag)202 void noteOngoingEventStopped(int userId, @NonNull String pkgName, int eventId, 203 @Nullable String tag); 204 } 205