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.permissioncontroller.permission.model.v34 18 19 import android.os.Build 20 import androidx.annotation.RequiresApi 21 import com.android.permission.safetylabel.DataCategoryConstants.CATEGORY_LOCATION 22 import com.android.permissioncontroller.permission.model.v34.DataSharingUpdateType.ADDS_ADVERTISING_PURPOSE 23 import com.android.permissioncontroller.permission.model.v34.DataSharingUpdateType.ADDS_SHARING_WITHOUT_ADVERTISING_PURPOSE 24 import com.android.permissioncontroller.permission.model.v34.DataSharingUpdateType.ADDS_SHARING_WITH_ADVERTISING_PURPOSE 25 import com.android.permissioncontroller.safetylabel.AppsSafetyLabelHistory.AppSafetyLabelDiff 26 import com.android.permissioncontroller.safetylabel.AppsSafetyLabelHistory.SafetyLabel 27 28 /** 29 * Class representing a significant update in an app's data sharing policy from its safety label. 30 * 31 * Note that safety labels are part of package information, and therefore the safety label 32 * information applies to apps for all users that have the app installed. 33 */ 34 @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) 35 data class AppDataSharingUpdate( 36 /** Package name for the app with the data sharing update. */ 37 val packageName: String, 38 /** How data sharing for each category has changed. */ 39 val categorySharingUpdates: Map<String, DataSharingUpdateType> 40 ) { 41 42 /** Companion object for [AppDataSharingUpdate]. */ 43 companion object { 44 /** 45 * Builds and returns an [AppDataSharingUpdate] from an [AppSafetyLabelDiff], if the change 46 * in safety labels is significant, else returns null. 47 */ buildUpdateIfSignificantChangenull48 fun AppSafetyLabelDiff.buildUpdateIfSignificantChange(): AppDataSharingUpdate? { 49 // In Android U, only updates for the location data category will be displayed in 50 // the UI. 51 val updates = getUpdatesForCategories(listOf(CATEGORY_LOCATION)) 52 53 return if (updates.isEmpty()) null 54 else AppDataSharingUpdate(safetyLabelBefore.appInfo.packageName, updates) 55 } 56 AppSafetyLabelDiffnull57 private fun AppSafetyLabelDiff.getUpdatesForCategories( 58 categories: List<String> 59 ): Map<String, DataSharingUpdateType> { 60 val categoryUpdateMap = mutableMapOf<String, DataSharingUpdateType>() 61 62 for (category in categories) { 63 var categoryUpdateType: DataSharingUpdateType? 64 65 val beforeSharesData = safetyLabelBefore.sharesData(category) 66 val beforeSharesDataForAds = safetyLabelBefore.sharesDataForAdsPurpose(category) 67 val afterSharesData = safetyLabelAfter.sharesData(category) 68 val afterSharesDataForAds = safetyLabelAfter.sharesDataForAdsPurpose(category) 69 70 categoryUpdateType = 71 when { 72 !beforeSharesData && afterSharesDataForAds -> 73 ADDS_SHARING_WITH_ADVERTISING_PURPOSE 74 !beforeSharesData && afterSharesData && !afterSharesDataForAds -> 75 ADDS_SHARING_WITHOUT_ADVERTISING_PURPOSE 76 beforeSharesData && !beforeSharesDataForAds && afterSharesDataForAds -> 77 ADDS_ADVERTISING_PURPOSE 78 else -> null 79 } 80 81 if (categoryUpdateType == null) { 82 continue 83 } 84 85 categoryUpdateMap[category] = categoryUpdateType 86 } 87 88 return categoryUpdateMap 89 } 90 SafetyLabelnull91 private fun SafetyLabel.sharesData(category: String) = 92 dataLabel.dataShared.containsKey(category) 93 94 private fun SafetyLabel.sharesDataForAdsPurpose(category: String) = 95 dataLabel.dataShared[category]?.containsAdvertisingPurpose ?: false 96 } 97 } 98 99 /** 100 * Different ways in which data sharing can be significantly updated for a particular data category. 101 */ 102 enum class DataSharingUpdateType { 103 ADDS_ADVERTISING_PURPOSE, 104 ADDS_SHARING_WITHOUT_ADVERTISING_PURPOSE, 105 ADDS_SHARING_WITH_ADVERTISING_PURPOSE 106 } 107