1 /* 2 * Copyright (C) 2022 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.data.enrollment; 18 19 import android.adservices.common.AdTechIdentifier; 20 import android.database.Cursor; 21 import android.net.Uri; 22 23 import com.android.adservices.LogUtil; 24 import com.android.adservices.service.enrollment.EnrollmentData; 25 26 import java.util.ArrayList; 27 import java.util.List; 28 import java.util.function.Function; 29 30 /** Helper class for SQLite operations. */ 31 public class SqliteObjectMapper { 32 /** Create {@link EnrollmentData} object from SQLite datastore. */ constructEnrollmentDataFromCursor(Cursor cursor)33 public static EnrollmentData constructEnrollmentDataFromCursor(Cursor cursor) { 34 EnrollmentData.Builder builder = new EnrollmentData.Builder(); 35 setTextColumn( 36 cursor, 37 EnrollmentTables.EnrollmentDataContract.ENROLLMENT_ID, 38 builder::setEnrollmentId); 39 setTextColumn( 40 cursor, 41 EnrollmentTables.EnrollmentDataContract.COMPANY_ID, 42 builder::setEnrolledAPIs); 43 setTextColumn( 44 cursor, EnrollmentTables.EnrollmentDataContract.SDK_NAMES, builder::setSdkNames); 45 setTextColumn( 46 cursor, 47 EnrollmentTables.EnrollmentDataContract.ATTRIBUTION_SOURCE_REGISTRATION_URL, 48 builder::setAttributionSourceRegistrationUrl); 49 setTextColumn( 50 cursor, 51 EnrollmentTables.EnrollmentDataContract.ATTRIBUTION_TRIGGER_REGISTRATION_URL, 52 builder::setAttributionTriggerRegistrationUrl); 53 setTextColumn( 54 cursor, 55 EnrollmentTables.EnrollmentDataContract.ATTRIBUTION_REPORTING_URL, 56 builder::setAttributionReportingUrl); 57 setTextColumn( 58 cursor, 59 EnrollmentTables.EnrollmentDataContract.REMARKETING_RESPONSE_BASED_REGISTRATION_URL, 60 builder::setRemarketingResponseBasedRegistrationUrl); 61 setTextColumn( 62 cursor, 63 EnrollmentTables.EnrollmentDataContract.ENCRYPTION_KEY_URL, 64 builder::setEncryptionKeyUrl); 65 setTextColumn( 66 cursor, 67 EnrollmentTables.EnrollmentDataContract.ENROLLED_SITE, 68 builder::setEnrolledSite); 69 setTextColumn( 70 cursor, 71 EnrollmentTables.EnrollmentDataContract.ENROLLED_APIS, 72 builder::setEnrolledAPIs); 73 return builder.build(); 74 } 75 76 /** 77 * Transforms the FLEDGE RBR URLs found at the given {@code cursor} to a list of {@link 78 * AdTechIdentifier} objects. 79 */ getAdTechIdentifiersFromFledgeCursor(Cursor cursor)80 public static List<AdTechIdentifier> getAdTechIdentifiersFromFledgeCursor(Cursor cursor) { 81 List<AdTechIdentifier> enrolledFledgeAdTechIdentifiers = new ArrayList<>(); 82 List<String> fledgeRbrUrls = new ArrayList<>(); 83 84 setTextColumn( 85 cursor, 86 EnrollmentTables.EnrollmentDataContract.REMARKETING_RESPONSE_BASED_REGISTRATION_URL, 87 input -> { 88 fledgeRbrUrls.addAll(EnrollmentData.splitEnrollmentInputToList(input)); 89 return null; 90 }); 91 92 for (String fledgeRbrUrl : fledgeRbrUrls) { 93 try { 94 if (fledgeRbrUrl != null && !fledgeRbrUrl.trim().isEmpty()) { 95 enrolledFledgeAdTechIdentifiers.add( 96 AdTechIdentifier.fromString(Uri.parse(fledgeRbrUrl).getHost())); 97 } 98 } catch (Exception exception) { 99 LogUtil.d(exception, "Failure parsing RBR URL \"%s\"; skipping", fledgeRbrUrl); 100 } 101 } 102 103 return enrolledFledgeAdTechIdentifiers; 104 } 105 106 /** 107 * Transforms the PAS urls found at the given {@code cursor} to a {@link AdTechIdentifier} 108 * objects. 109 */ getAdTechIdentifierFromPASCursor(Cursor cursor)110 static AdTechIdentifier getAdTechIdentifierFromPASCursor(Cursor cursor) { 111 112 List<String> pasUrls = new ArrayList<>(); 113 AdTechIdentifier enrolledPASAdTechIdentifier = null; 114 115 setTextColumn( 116 cursor, 117 EnrollmentTables.EnrollmentDataContract.ENCRYPTION_KEY_URL, 118 input -> { 119 pasUrls.add(input); 120 return null; 121 }); 122 123 for (String pasUrl : pasUrls) { 124 try { 125 if (pasUrl != null && !pasUrl.trim().isEmpty()) { 126 enrolledPASAdTechIdentifier = 127 AdTechIdentifier.fromString(Uri.parse(pasUrl).getHost()); 128 } 129 } catch (Exception exception) { 130 LogUtil.d(exception, "Failure parsing PAS URL \"%s\"; skipping", pasUrl); 131 } 132 } 133 134 return enrolledPASAdTechIdentifier; 135 } 136 setTextColumn( Cursor cursor, String column, Function<String, BuilderType> setter)137 private static <BuilderType> void setTextColumn( 138 Cursor cursor, String column, Function<String, BuilderType> setter) { 139 setColumnValue(cursor, column, cursor::getString, setter); 140 } 141 142 @SuppressWarnings("ReturnValueIgnored") setColumnValue( Cursor cursor, String column, Function<Integer, DataType> getColVal, Function<DataType, BuilderType> setter)143 private static <BuilderType, DataType> void setColumnValue( 144 Cursor cursor, 145 String column, 146 Function<Integer, DataType> getColVal, 147 Function<DataType, BuilderType> setter) { 148 int index = cursor.getColumnIndex(column); 149 if (index > -1 && !cursor.isNull(index)) { 150 setter.apply(getColVal.apply(index)); 151 } 152 } 153 } 154