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.adselection; 18 19 import android.adservices.common.AdTechIdentifier; 20 import android.content.pm.PackageManager; 21 22 import androidx.annotation.NonNull; 23 import androidx.room.Dao; 24 import androidx.room.Insert; 25 import androidx.room.OnConflictStrategy; 26 import androidx.room.Query; 27 import androidx.room.Transaction; 28 29 import com.android.adservices.data.common.CleanupUtils; 30 import com.android.adservices.service.Flags; 31 32 import java.util.Arrays; 33 import java.util.List; 34 import java.util.Objects; 35 36 /** 37 * Data access object abstract class for running app install related queries. 38 * 39 * <p>Annotation will generate Room based SQLite Dao implementation. 40 */ 41 @Dao 42 public abstract class AppInstallDao { 43 44 /** 45 * Checks if a buyer is allowed to filter a given package. 46 * 47 * @param buyer the name of the buyer. 48 * @param packageName the name of the package. 49 * @return true if the (buyer, package name) pair is in the database, false otherwise 50 */ 51 @Query( 52 "SELECT EXISTS(SELECT 1 FROM app_install WHERE buyer = :buyer" 53 + " AND package_name = :packageName)") canBuyerFilterPackage( @onNull AdTechIdentifier buyer, @NonNull String packageName)54 public abstract boolean canBuyerFilterPackage( 55 @NonNull AdTechIdentifier buyer, @NonNull String packageName); 56 57 /** 58 * Insert new buyer, package pairs which will allow the buyer to filter on the package. If the 59 * entry already exists, nothing is inserted or changed. 60 * 61 * @param appInstalls The buyer, package pairs to insert 62 */ 63 @Insert(onConflict = OnConflictStrategy.IGNORE) insertAllAppInstallPermissions( @onNull List<DBAppInstallPermissions> appInstalls)64 protected abstract void insertAllAppInstallPermissions( 65 @NonNull List<DBAppInstallPermissions> appInstalls); 66 67 /** 68 * Get all the packages names with app install data. 69 * 70 * @return A list of all packages with entries in the app install table. 71 */ 72 @Query("SELECT package_name FROM app_install") getAllPackageNames()73 protected abstract List<String> getAllPackageNames(); 74 75 /** 76 * Removes all entries associated with any package in the given list. 77 * 78 * @param packageNames the list of packages. 79 */ 80 @Query("DELETE FROM app_install WHERE package_name IN (:packageNames)") deleteByPackageNames(@onNull List<String> packageNames)81 protected abstract int deleteByPackageNames(@NonNull List<String> packageNames); 82 83 /** 84 * Removes all entries associated with a package 85 * 86 * @param packageName The name of the package. 87 */ 88 @Query("DELETE FROM app_install WHERE package_name = :packageName") deleteByPackageName(@onNull String packageName)89 public abstract int deleteByPackageName(@NonNull String packageName); 90 91 /** Deletes ALL app install data from the database. */ 92 @Query("DELETE FROM app_install") deleteAllAppInstallData()93 public abstract void deleteAllAppInstallData(); 94 95 /** 96 * Runs deleteByPackageName on the given packagename then insertAllAppInstallPermissions on the 97 * given list of DBAppInstallPermissions in a single transaction. Note that there is no that the 98 * package/packages in the DBAppInstallPermissions match the packageName parameter. 99 * 100 * @param packageName The package name to clear all entries for 101 * @param appInstalls The DBAppInstallPermissions to insert 102 */ 103 @Transaction setAdTechsForPackage( @onNull String packageName, @NonNull List<DBAppInstallPermissions> appInstalls)104 public void setAdTechsForPackage( 105 @NonNull String packageName, @NonNull List<DBAppInstallPermissions> appInstalls) { 106 deleteByPackageName(packageName); 107 insertAllAppInstallPermissions(appInstalls); 108 } 109 110 /** 111 * Deletes all app install data belonging to disallowed packages in a single transaction. 112 * 113 * <p>Disallowed means package cannot be found in the installed list or that the package is not 114 * found in the ppapi allowlist. 115 * 116 * <p>TODO(b/272537512): Consider returning more information 117 * 118 * @return the number of entries removed 119 */ 120 @Transaction 121 @NonNull deleteAllDisallowedPackageEntries( @onNull PackageManager packageManager, @NonNull Flags flags)122 public int deleteAllDisallowedPackageEntries( 123 @NonNull PackageManager packageManager, @NonNull Flags flags) { 124 Objects.requireNonNull(packageManager); 125 Objects.requireNonNull(flags); 126 127 List<String> packagesToRemove = getAllPackageNames(); 128 CleanupUtils.removeAllowedPackages( 129 packagesToRemove, 130 packageManager, 131 Arrays.asList(flags.getPpapiAppAllowList(), flags.getPasAppAllowList())); 132 if (packagesToRemove.isEmpty()) { 133 return 0; 134 } 135 return deleteByPackageNames(packagesToRemove); 136 } 137 } 138