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 android.annotation.NonNull; 20 import android.annotation.Nullable; 21 22 import java.util.Objects; 23 24 /** 25 * POJO for key-value data. 26 * 27 * <p>This class is useful for creating & storing arbitrary key-value-dataType combinations. The 28 * corresponding table {@code 29 * com.android.adservices.data.measurement.MeasurementTables.KeyValueDataContract} is used to 30 * persist these objects. 31 */ 32 public class KeyValueData { 33 34 35 public enum DataType { 36 REGISTRATION_REDIRECT_COUNT, 37 EVENT_REPORT_RETRY_COUNT, 38 DEBUG_EVENT_REPORT_RETRY_COUNT, 39 AGGREGATE_REPORT_RETRY_COUNT, 40 DEBUG_AGGREGATE_REPORT_RETRY_COUNT, 41 DEBUG_REPORT_RETRY_COUNT, 42 JOB_LAST_EXECUTION_TIME, 43 JOB_NEXT_EXECUTION_TIME, 44 } 45 46 private DataType mDataType = null; 47 private String mKey = null; 48 private String mValue = null; 49 KeyValueData(DataType dataType, String key, String value)50 private KeyValueData(DataType dataType, String key, String value) { 51 mDataType = dataType; 52 mKey = key; 53 mValue = value; 54 } 55 56 /** Returns the data type. */ getDataType()57 public DataType getDataType() { 58 return mDataType; 59 } 60 61 /** Returns the key. */ getKey()62 public String getKey() { 63 return mKey; 64 } 65 66 /** Returns the raw value. */ getValue()67 public String getValue() { 68 return mValue; 69 } 70 KeyValueData()71 private KeyValueData() {} 72 73 /** Builder class for {@link KeyValueData} */ 74 public static class Builder { 75 private DataType mDataType = null; 76 private String mKey = null; 77 private String mValue = null; 78 79 /** See {@link KeyValueData#getDataType()} ()} */ setDataType(@onNull DataType dataType)80 public Builder setDataType(@NonNull DataType dataType) { 81 mDataType = dataType; 82 return this; 83 } 84 85 /** See {@link KeyValueData#getKey()} */ setKey(@onNull String key)86 public Builder setKey(@NonNull String key) { 87 mKey = key; 88 return this; 89 } 90 91 /** See {@link KeyValueData#getValue()} */ setValue(@ullable String value)92 public Builder setValue(@Nullable String value) { 93 mValue = value; 94 return this; 95 } 96 97 /** Build the {@link KeyValueData} */ build()98 public KeyValueData build() { 99 Objects.requireNonNull(mDataType); 100 Objects.requireNonNull(mKey); 101 return new KeyValueData(mDataType, mKey, mValue); 102 } 103 } 104 105 /** Get the Registration Count value */ getRegistrationRedirectCount()106 public int getRegistrationRedirectCount() { 107 if (mDataType != DataType.REGISTRATION_REDIRECT_COUNT) { 108 throw new IllegalStateException("Illegal method call"); 109 } 110 if (mValue == null) { 111 // Default value is 1, because the first registration will be the only case when value 112 // can be null. 113 return 1; 114 } 115 return Integer.parseInt(mValue); 116 } 117 118 /** Set the Registration Count value */ setRegistrationRedirectCount(int value)119 public void setRegistrationRedirectCount(int value) { 120 if (mDataType != DataType.REGISTRATION_REDIRECT_COUNT) { 121 throw new IllegalStateException("Illegal method call"); 122 } 123 mValue = String.valueOf(value); 124 } 125 126 /** Set the Aggregate/Event/Debug Report Retry Count value */ getReportRetryCount()127 public int getReportRetryCount() { 128 validateOfTypeReport(); 129 if (mValue == null) { 130 // Default value is 0, 131 return 0; 132 } 133 return Integer.parseInt(mValue); 134 } 135 136 /** Set the Aggregate/Event/Debug Report Retry Count value */ setReportRetryCount(int value)137 public void setReportRetryCount(int value) { 138 validateOfTypeReport(); 139 mValue = String.valueOf(value); 140 } 141 142 /** Get the last execution time of the Reporting Service Job */ getReportingJobLastExecutionTime()143 public Long getReportingJobLastExecutionTime() { 144 validateOfTypeReport(); 145 if (mValue == null) { 146 return null; 147 } 148 return Long.parseLong(mValue); 149 } 150 151 /** Set the last execution time of the Reporting Service Job */ setReportingJobLastExecutionTime(long value)152 public void setReportingJobLastExecutionTime(long value) { 153 validateOfTypeReport(); 154 mValue = String.valueOf(value); 155 } 156 157 /** Get the next execution time of the Reporting Service Job */ getReportingJobNextExecutionTime()158 public Long getReportingJobNextExecutionTime() { 159 validateOfTypeReport(); 160 if (mValue == null) { 161 return null; 162 } 163 return Long.parseLong(mValue); 164 } 165 166 /** Set the next execution time of the Reporting Service Job */ setReportingJobNextExecutionTime(Long value)167 public void setReportingJobNextExecutionTime(Long value) { 168 validateOfTypeReport(); 169 mValue = String.valueOf(value); 170 } 171 validateOfTypeReport()172 private void validateOfTypeReport() { 173 if (mDataType != DataType.AGGREGATE_REPORT_RETRY_COUNT 174 && mDataType != DataType.DEBUG_AGGREGATE_REPORT_RETRY_COUNT 175 && mDataType != DataType.EVENT_REPORT_RETRY_COUNT 176 && mDataType != DataType.DEBUG_EVENT_REPORT_RETRY_COUNT 177 && mDataType != DataType.DEBUG_REPORT_RETRY_COUNT 178 && mDataType != DataType.JOB_LAST_EXECUTION_TIME 179 && mDataType != DataType.JOB_NEXT_EXECUTION_TIME) { 180 throw new IllegalStateException("Illegal method call"); 181 } 182 } 183 } 184