1 /* 2 * Copyright (C) 2023 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.adservices.service.measurement; 18 19 import com.android.adservices.LoggerFactory; 20 import com.android.adservices.service.measurement.util.UnsignedLong; 21 22 import org.json.JSONException; 23 import org.json.JSONObject; 24 25 import java.util.Objects; 26 27 /** POJO for attributed trigger. */ 28 public class AttributedTrigger { 29 private final String mTriggerId; 30 private final long mPriority; 31 private final UnsignedLong mTriggerData; 32 private final long mValue; 33 private final long mTriggerTime; 34 private final UnsignedLong mDedupKey; 35 private final UnsignedLong mDebugKey; 36 private final Boolean mHasSourceDebugKey; 37 private long mContribution; 38 39 @Override equals(Object obj)40 public boolean equals(Object obj) { 41 if (!(obj instanceof AttributedTrigger)) { 42 return false; 43 } 44 AttributedTrigger t = (AttributedTrigger) obj; 45 46 return mTriggerId.equals(t.mTriggerId) 47 && mPriority == t.mPriority 48 && Objects.equals(mTriggerData, t.mTriggerData) 49 && mValue == t.mValue 50 && mTriggerTime == t.mTriggerTime 51 && Objects.equals(mDedupKey, t.mDedupKey) 52 && Objects.equals(mDebugKey, t.mDebugKey) 53 && Objects.equals(mHasSourceDebugKey, t.mHasSourceDebugKey); 54 } 55 56 @Override hashCode()57 public int hashCode() { 58 return Objects.hash( 59 mTriggerId, 60 mPriority, 61 mTriggerData, 62 mValue, 63 mTriggerTime, 64 mDedupKey, 65 mDebugKey, 66 mHasSourceDebugKey); 67 } 68 AttributedTrigger(JSONObject json)69 public AttributedTrigger(JSONObject json) throws JSONException { 70 mTriggerId = json.getString(JsonKeys.TRIGGER_ID); 71 if (!json.isNull(TriggerSpecs.FlexEventReportJsonKeys.PRIORITY)) { 72 mPriority = json.getLong(TriggerSpecs.FlexEventReportJsonKeys.PRIORITY); 73 } else { 74 mPriority = 0L; 75 } 76 if (!json.isNull(TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_DATA)) { 77 mTriggerData = new UnsignedLong( 78 json.getString(TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_DATA)); 79 } else { 80 mTriggerData = null; 81 } 82 if (!json.isNull(TriggerSpecs.FlexEventReportJsonKeys.VALUE)) { 83 mValue = json.getLong(TriggerSpecs.FlexEventReportJsonKeys.VALUE); 84 } else { 85 mValue = 0L; 86 } 87 if (!json.isNull(TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_TIME)) { 88 mTriggerTime = json.getLong(TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_TIME); 89 } else { 90 mTriggerTime = 0L; 91 } 92 if (!json.isNull(JsonKeys.DEDUP_KEY)) { 93 mDedupKey = new UnsignedLong( 94 json.getString(JsonKeys.DEDUP_KEY)); 95 } else { 96 mDedupKey = null; 97 } 98 if (!json.isNull(JsonKeys.DEBUG_KEY)) { 99 mDebugKey = new UnsignedLong( 100 json.getString(JsonKeys.DEBUG_KEY)); 101 } else { 102 mDebugKey = null; 103 } 104 if (!json.isNull(JsonKeys.HAS_SOURCE_DEBUG_KEY)) { 105 mHasSourceDebugKey = json.getBoolean(JsonKeys.HAS_SOURCE_DEBUG_KEY); 106 } else { 107 mHasSourceDebugKey = null; 108 } 109 } 110 AttributedTrigger( String triggerId, UnsignedLong triggerData, UnsignedLong dedupKey)111 public AttributedTrigger( 112 String triggerId, 113 UnsignedLong triggerData, 114 UnsignedLong dedupKey) { 115 mTriggerId = triggerId; 116 mDedupKey = dedupKey; 117 mDebugKey = null; 118 mHasSourceDebugKey = null; 119 mPriority = 0L; 120 mTriggerData = triggerData; 121 mValue = 0L; 122 mTriggerTime = 0L; 123 } 124 AttributedTrigger( String triggerId, long priority, UnsignedLong triggerData, long value, long triggerTime, UnsignedLong dedupKey, UnsignedLong debugKey, boolean hasSourceDebugKey)125 public AttributedTrigger( 126 String triggerId, 127 long priority, 128 UnsignedLong triggerData, 129 long value, 130 long triggerTime, 131 UnsignedLong dedupKey, 132 UnsignedLong debugKey, 133 boolean hasSourceDebugKey) { 134 mTriggerId = triggerId; 135 mPriority = priority; 136 mTriggerData = triggerData; 137 mValue = value; 138 mTriggerTime = triggerTime; 139 mDedupKey = dedupKey; 140 mDebugKey = debugKey; 141 mHasSourceDebugKey = hasSourceDebugKey; 142 } 143 getTriggerId()144 public String getTriggerId() { 145 return mTriggerId; 146 } 147 getPriority()148 public long getPriority() { 149 return mPriority; 150 } 151 getTriggerData()152 public UnsignedLong getTriggerData() { 153 return mTriggerData; 154 } 155 getValue()156 public long getValue() { 157 return mValue; 158 } 159 getTriggerTime()160 public long getTriggerTime() { 161 return mTriggerTime; 162 } 163 getDedupKey()164 public UnsignedLong getDedupKey() { 165 return mDedupKey; 166 } 167 getDebugKey()168 public UnsignedLong getDebugKey() { 169 return mDebugKey; 170 } 171 172 /** 173 * Returns whether the source debug key was permitted and populated when this trigger was 174 * attributed. 175 */ hasSourceDebugKey()176 public boolean hasSourceDebugKey() { 177 return mHasSourceDebugKey; 178 } 179 getContribution()180 public long getContribution() { 181 return mContribution; 182 } 183 184 /** Adds to the attributed trigger's contribution. */ addContribution(long contribution)185 public void addContribution(long contribution) { 186 mContribution += contribution; 187 } 188 189 /** Returns the remaining value this attributed trigger can contribute to summary buckets. */ remainingValue()190 public long remainingValue() { 191 return getValue() - getContribution(); 192 } 193 194 /** Encodes the attributed trigger to a JSONObject */ encodeToJson()195 public JSONObject encodeToJson() { 196 JSONObject json = new JSONObject(); 197 try { 198 json.put(JsonKeys.TRIGGER_ID, mTriggerId); 199 json.put( 200 TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_DATA, 201 mTriggerData.toString()); 202 json.put(JsonKeys.DEDUP_KEY, mDedupKey.toString()); 203 } catch (JSONException e) { 204 LoggerFactory.getMeasurementLogger() 205 .e(e, "AttributedTrigger::encodeToJson cannot encode to JSON"); 206 return null; 207 } 208 return json; 209 } 210 211 /** Encodes the attributed trigger to a JSONObject */ encodeToJsonFlexApi()212 public JSONObject encodeToJsonFlexApi() { 213 JSONObject json = new JSONObject(); 214 try { 215 json.put(JsonKeys.TRIGGER_ID, mTriggerId); 216 json.put( 217 TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_DATA, 218 mTriggerData.toString()); 219 json.put(TriggerSpecs.FlexEventReportJsonKeys.TRIGGER_TIME, mTriggerTime); 220 json.put(TriggerSpecs.FlexEventReportJsonKeys.VALUE, mValue); 221 if (mDedupKey != null) { 222 json.put(JsonKeys.DEDUP_KEY, mDedupKey.toString()); 223 } 224 if (mDebugKey != null) { 225 json.put(JsonKeys.DEBUG_KEY, mDebugKey.toString()); 226 } 227 json.put(JsonKeys.HAS_SOURCE_DEBUG_KEY, mHasSourceDebugKey); 228 json.put(TriggerSpecs.FlexEventReportJsonKeys.PRIORITY, mPriority); 229 } catch (JSONException e) { 230 LoggerFactory.getMeasurementLogger() 231 .e( 232 e, 233 "AttributedTrigger::encodeToJsonFlexApi cannot encode to JSON"); 234 return null; 235 } 236 return json; 237 } 238 239 private interface JsonKeys { 240 String TRIGGER_ID = "trigger_id"; 241 String DEDUP_KEY = "dedup_key"; 242 String DEBUG_KEY = "debug_key"; 243 String HAS_SOURCE_DEBUG_KEY = "has_source_debug_key"; 244 } 245 } 246