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.ondevicepersonalization.services.util; 18 19 import android.ondevicepersonalization.ExecuteOutput; 20 import android.ondevicepersonalization.SlotResult; 21 22 import com.android.ondevicepersonalization.services.fbs.Bid; 23 import com.android.ondevicepersonalization.services.fbs.EventFields; 24 import com.android.ondevicepersonalization.services.fbs.Metrics; 25 import com.android.ondevicepersonalization.services.fbs.Owner; 26 import com.android.ondevicepersonalization.services.fbs.QueryData; 27 import com.android.ondevicepersonalization.services.fbs.QueryFields; 28 import com.android.ondevicepersonalization.services.fbs.Slot; 29 30 import com.google.flatbuffers.FlatBufferBuilder; 31 32 import java.util.List; 33 34 /** 35 * Util class to support creation of OnDevicePersonalization flatbuffers 36 */ 37 public class OnDevicePersonalizationFlatbufferUtils { OnDevicePersonalizationFlatbufferUtils()38 private OnDevicePersonalizationFlatbufferUtils() { 39 } 40 41 /** 42 * Creates a byte array representing the QueryData as a flatbuffer 43 */ createQueryData( String servicePackageName, String certDigest, ExecuteOutput executeOutput)44 public static byte[] createQueryData( 45 String servicePackageName, String certDigest, ExecuteOutput executeOutput) { 46 FlatBufferBuilder builder = new FlatBufferBuilder(); 47 int ownerOffset = createOwner(builder, servicePackageName, certDigest); 48 int slotsOffset = 0; 49 if (executeOutput.getSlotResults() != null) { 50 // Create slots vector 51 List<SlotResult> slotResults = executeOutput.getSlotResults(); 52 int[] slots = new int[slotResults.size()]; 53 for (int i = 0; i < slotResults.size(); i++) { 54 SlotResult slotResult = slotResults.get(i); 55 int slotKeyOffset = builder.createString(slotResult.getSlotKey()); 56 57 int bidsOffset = 0; 58 if (slotResult.getLoggedBids() != null) { 59 bidsOffset = createBidVector(builder, slotResult.getLoggedBids()); 60 } 61 62 Slot.startSlot(builder); 63 Slot.addKey(builder, slotKeyOffset); 64 Slot.addBids(builder, bidsOffset); 65 slots[i] = Slot.endSlot(builder); 66 } 67 slotsOffset = QueryFields.createSlotsVector(builder, slots); 68 } 69 QueryFields.startQueryFields(builder); 70 QueryFields.addOwner(builder, ownerOffset); 71 QueryFields.addSlots(builder, slotsOffset); 72 int[] queryFieldsOffset = new int[1]; 73 queryFieldsOffset[0] = QueryFields.endQueryFields(builder); 74 int queryFieldsListOffset = QueryData.createQueryFieldsVector(builder, queryFieldsOffset); 75 QueryData.startQueryData(builder); 76 QueryData.addQueryFields(builder, queryFieldsListOffset); 77 int queryDataOffset = QueryData.endQueryData(builder); 78 builder.finish(queryDataOffset); 79 return builder.sizedByteArray(); 80 } 81 82 /** 83 * Creates a byte array representing the EventData as a flatbuffer 84 */ createEventData(android.ondevicepersonalization.Metrics metrics)85 public static byte[] createEventData(android.ondevicepersonalization.Metrics metrics) { 86 FlatBufferBuilder builder = new FlatBufferBuilder(); 87 int metricsOffset = 0; 88 if (metrics != null) { 89 metricsOffset = createMetrics(builder, metrics); 90 } 91 EventFields.startEventFields(builder); 92 EventFields.addMetrics(builder, metricsOffset); 93 int eventFieldsOffset = EventFields.endEventFields(builder); 94 builder.finish(eventFieldsOffset); 95 return builder.sizedByteArray(); 96 } 97 createOwner( FlatBufferBuilder builder, String packageName, String certDigest)98 private static int createOwner( 99 FlatBufferBuilder builder, 100 String packageName, 101 String certDigest) { 102 int packageNameOffset = 0; 103 if (packageName != null) { 104 packageNameOffset = builder.createString(packageName); 105 } 106 int certDigestOffset = 0; 107 if (certDigest != null) { 108 certDigestOffset = builder.createString(certDigest); 109 } 110 Owner.startOwner(builder); 111 Owner.addPackageName(builder, packageNameOffset); 112 Owner.addCertDigest(builder, certDigestOffset); 113 return Owner.endOwner(builder); 114 } 115 createBidVector( FlatBufferBuilder builder, List<android.ondevicepersonalization.Bid> bids)116 private static int createBidVector( 117 FlatBufferBuilder builder, 118 List<android.ondevicepersonalization.Bid> bids) { 119 int[] loggedBids = new int[bids.size()]; 120 for (int i = 0; i < bids.size(); i++) { 121 android.ondevicepersonalization.Bid bid = bids.get(i); 122 int bidKeyOffset = builder.createString(bid.getKey()); 123 int metricsOffset = 0; 124 if (bid.getMetrics() != null) { 125 metricsOffset = createMetrics(builder, bid.getMetrics()); 126 } 127 Bid.startBid(builder); 128 Bid.addKey(builder, bidKeyOffset); 129 Bid.addMetrics(builder, metricsOffset); 130 loggedBids[i] = Bid.endBid(builder); 131 } 132 return Slot.createBidsVector(builder, loggedBids); 133 } 134 createMetrics(FlatBufferBuilder builder, android.ondevicepersonalization.Metrics metrics)135 private static int createMetrics(FlatBufferBuilder builder, 136 android.ondevicepersonalization.Metrics metrics) { 137 int intValuesOffset = 0; 138 if (metrics.getLongValues() != null) { 139 intValuesOffset = Metrics.createLongValuesVector(builder, metrics.getLongValues()); 140 } 141 int floatValuesOffset = 0; 142 if (metrics.getDoubleValues() != null) { 143 floatValuesOffset = Metrics.createDoubleValuesVector( 144 builder, metrics.getDoubleValues()); 145 } 146 int booleanValuesOffset = 0; 147 if (metrics.getBooleanValues() != null) { 148 booleanValuesOffset = Metrics.createBooleanValuesVector( 149 builder, metrics.getBooleanValues()); 150 } 151 Metrics.startMetrics(builder); 152 Metrics.addLongValues(builder, intValuesOffset); 153 Metrics.addDoubleValues(builder, floatValuesOffset); 154 Metrics.addBooleanValues(builder, booleanValuesOffset); 155 return Metrics.endMetrics(builder); 156 } 157 } 158