1 /* 2 * Copyright (C) 2024 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 android.adservices.ondevicepersonalization; 18 19 import static android.adservices.ondevicepersonalization.ExecuteInIsolatedServiceResponse.DEFAULT_BEST_VALUE; 20 21 import android.annotation.FlaggedApi; 22 import android.annotation.IntDef; 23 import android.annotation.IntRange; 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.content.ComponentName; 27 import android.os.PersistableBundle; 28 29 import com.android.adservices.ondevicepersonalization.flags.Flags; 30 import com.android.ondevicepersonalization.internal.util.AnnotationValidations; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 import java.util.Objects; 35 36 /** The request of {@link OnDevicePersonalizationManager#executeInIsolatedService}. */ 37 @FlaggedApi(Flags.FLAG_EXECUTE_IN_ISOLATED_SERVICE_API_ENABLED) 38 public class ExecuteInIsolatedServiceRequest { 39 /** The {@link ComponentName} of the {@link IsolatedService}. */ 40 @NonNull private ComponentName mService; 41 42 /** 43 * A {@link PersistableBundle} that is passed from the calling app to the {@link 44 * IsolatedService}. The expected contents of this parameter are defined by the {@link 45 * IsolatedService}. The platform does not interpret this parameter. 46 */ 47 @NonNull private PersistableBundle mAppParams; 48 49 /** 50 * The set of spec to indicate output of {@link IsolatedService}. It's mainly used by platform. 51 * If {@link OutputSpec} is set to {@link OutputSpec#DEFAULT}, OnDevicePersonalization will 52 * ignore result returned by {@link IsolatedService}. If {@link OutputSpec} is built with {@link 53 * OutputSpec#buildBestValueSpec}, OnDevicePersonalization will verify {@link 54 * ExecuteOutput#getBestValue()} returned by {@link IsolatedService} within the max value range 55 * set in {@link OutputSpec#getMaxIntValue} and add noise. 56 */ 57 @NonNull private OutputSpec mOutputSpec; 58 59 /** 60 * The set of spec to indicate output of {@link IsolatedService}. It's mainly used by platform. 61 * If {@link OutputSpec} is set to {@link OutputSpec#DEFAULT}, OnDevicePersonalization will 62 * ignore result returned by {@link IsolatedService}. If {@link OutputSpec} is built with {@link 63 * OutputSpec#buildBestValueSpec}, OnDevicePersonalization will verify {@link 64 * ExecuteOutput#getBestValue()} returned by {@link IsolatedService} within the max value range 65 * set in {@link OutputSpec#getMaxIntValue} and add noise. 66 */ 67 public static class OutputSpec { 68 /** 69 * The default value of OutputType. If set, OnDevicePersonalization will ignore result 70 * returned by {@link IsolatedService} and {@link ExecuteInIsolatedServiceResponse} doesn't 71 * return any output data. 72 */ 73 public static final int OUTPUT_TYPE_NULL = 0; 74 75 /** 76 * If set, {@link ExecuteInIsolatedServiceResponse#getBestValue()} will return an integer 77 * that indicates the index of best values passed in {@link 78 * ExecuteInIsolatedServiceRequest#getAppParams}. 79 */ 80 public static final int OUTPUT_TYPE_BEST_VALUE = 1; 81 82 /** @hide */ 83 @IntDef( 84 prefix = "OUTPUT_TYPE_", 85 value = {OUTPUT_TYPE_NULL, OUTPUT_TYPE_BEST_VALUE}) 86 @Retention(RetentionPolicy.SOURCE) 87 public @interface OutputType {} 88 89 /** Default value is OUTPUT_TYPE_NULL. */ 90 @OutputType private final int mOutputType; 91 92 /** Optional. Only set when output option is OUTPUT_TYPE_BEST_VALUE. */ 93 @IntRange(from = DEFAULT_BEST_VALUE) 94 private final int mMaxIntValue; 95 96 /** The default value of {@link OutputSpec}. */ 97 @NonNull 98 public static final OutputSpec DEFAULT = 99 new OutputSpec(OUTPUT_TYPE_NULL, DEFAULT_BEST_VALUE); 100 OutputSpec(int outputType, int maxIntValue)101 private OutputSpec(int outputType, int maxIntValue) { 102 mMaxIntValue = maxIntValue; 103 mOutputType = outputType; 104 } 105 106 /** 107 * Creates the output spec to get best value out of {@code maxIntValue}. If set this, caller 108 * can call {@link ExecuteInIsolatedServiceResponse#getBestValue} to get result. 109 * 110 * @param maxIntValue the maximum value {@link IsolatedWorker} can return to caller app. 111 */ buildBestValueSpec(@ntRangefrom = 0) int maxIntValue)112 public @NonNull static OutputSpec buildBestValueSpec(@IntRange(from = 0) int maxIntValue) { 113 AnnotationValidations.validate(IntRange.class, null, maxIntValue, "from", 0); 114 return new OutputSpec(OUTPUT_TYPE_BEST_VALUE, maxIntValue); 115 } 116 117 /** 118 * Returns the output type of {@link IsolatedService}. The default value is {@link 119 * OutputSpec#OUTPUT_TYPE_NULL}. 120 */ getOutputType()121 public @OutputType int getOutputType() { 122 return mOutputType; 123 } 124 125 /** 126 * Returns the value set in {@link OutputSpec#buildBestValueSpec}. The value is expected to 127 * be {@link ExecuteInIsolatedServiceResponse#DEFAULT_BEST_VALUE} if {@link #getOutputType} 128 * is {@link OutputSpec#OUTPUT_TYPE_NULL}. 129 */ getMaxIntValue()130 public @IntRange(from = DEFAULT_BEST_VALUE) int getMaxIntValue() { 131 return mMaxIntValue; 132 } 133 } 134 ExecuteInIsolatedServiceRequest( @onNull ComponentName service, @NonNull PersistableBundle appParams, @NonNull OutputSpec outputSpec)135 /* package-private */ ExecuteInIsolatedServiceRequest( 136 @NonNull ComponentName service, 137 @NonNull PersistableBundle appParams, 138 @NonNull OutputSpec outputSpec) { 139 Objects.requireNonNull(service); 140 Objects.requireNonNull(appParams); 141 Objects.requireNonNull(outputSpec); 142 this.mService = service; 143 this.mAppParams = appParams; 144 this.mOutputSpec = outputSpec; 145 } 146 147 /** The {@link ComponentName} of the {@link IsolatedService}. */ getService()148 public @NonNull ComponentName getService() { 149 return mService; 150 } 151 152 /** 153 * A {@link PersistableBundle} that is passed from the calling app to the {@link 154 * IsolatedService}. The expected contents of this parameter are defined by the {@link 155 * IsolatedService}. The platform does not interpret this parameter. 156 */ getAppParams()157 public @NonNull PersistableBundle getAppParams() { 158 return mAppParams; 159 } 160 161 /** 162 * The set of spec to indicate output of {@link IsolatedService}. It's mainly used by platform. 163 * For example, platform calls {@link OutputSpec#getOutputType} and validates the result 164 * received from {@link IsolatedService}. 165 */ getOutputSpec()166 public @NonNull OutputSpec getOutputSpec() { 167 return mOutputSpec; 168 } 169 170 @Override equals(@ullable Object o)171 public boolean equals(@Nullable Object o) { 172 // You can override field equality logic by defining either of the methods like: 173 // boolean fieldNameEquals(ExecuteInIsolatedServiceRequest other) { ... } 174 // boolean fieldNameEquals(FieldType otherValue) { ... } 175 176 if (this == o) return true; 177 if (o == null || getClass() != o.getClass()) return false; 178 ExecuteInIsolatedServiceRequest that = (ExecuteInIsolatedServiceRequest) o; 179 //noinspection PointlessBooleanExpression 180 return java.util.Objects.equals(mService, that.mService) 181 && java.util.Objects.equals(mAppParams, that.mAppParams) 182 && java.util.Objects.equals(mOutputSpec, that.mOutputSpec); 183 } 184 185 @Override hashCode()186 public int hashCode() { 187 // You can override field hashCode logic by defining methods like: 188 // int fieldNameHashCode() { ... } 189 190 int _hash = 1; 191 _hash = 31 * _hash + java.util.Objects.hashCode(mService); 192 _hash = 31 * _hash + java.util.Objects.hashCode(mAppParams); 193 _hash = 31 * _hash + java.util.Objects.hashCode(mOutputSpec); 194 return _hash; 195 } 196 197 /** A builder for {@link ExecuteInIsolatedServiceRequest} */ 198 public static final class Builder { 199 200 private @NonNull ComponentName mService; 201 private @NonNull PersistableBundle mAppParams = PersistableBundle.EMPTY; 202 private @NonNull OutputSpec mOutputSpec = OutputSpec.DEFAULT; 203 204 /** 205 * Creates a new Builder. 206 * 207 * @param service The {@link ComponentName} of the {@link IsolatedService}. 208 */ Builder(@onNull ComponentName service)209 public Builder(@NonNull ComponentName service) { 210 Objects.requireNonNull(service); 211 mService = service; 212 } 213 214 /** 215 * A {@link PersistableBundle} that is passed from the calling app to the {@link 216 * IsolatedService}. The expected contents of this parameter are defined by the {@link 217 * IsolatedService}. The platform does not interpret this parameter. 218 */ setAppParams(@onNull PersistableBundle value)219 public @NonNull Builder setAppParams(@NonNull PersistableBundle value) { 220 Objects.requireNonNull(value); 221 mAppParams = value; 222 return this; 223 } 224 225 /** 226 * The set of spec to indicate output of {@link IsolatedService}. It's mainly used by 227 * platform. If {@link OutputSpec} is set to {@link OutputSpec#DEFAULT}, 228 * OnDevicePersonalization will ignore result returned by {@link IsolatedService}. If {@link 229 * OutputSpec} is built with {@link OutputSpec#buildBestValueSpec}, OnDevicePersonalization 230 * will verify {@link ExecuteOutput#getBestValue()} returned by {@link IsolatedService} 231 * within the max value range set in {@link OutputSpec#getMaxIntValue} and add noise. 232 */ setOutputSpec(@onNull OutputSpec value)233 public @NonNull Builder setOutputSpec(@NonNull OutputSpec value) { 234 Objects.requireNonNull(value); 235 mOutputSpec = value; 236 return this; 237 } 238 239 /** Builds the instance. */ build()240 public @NonNull ExecuteInIsolatedServiceRequest build() { 241 return new ExecuteInIsolatedServiceRequest(mService, mAppParams, mOutputSpec); 242 } 243 } 244 } 245