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