Create user profile ID when Fledge consent is grant and clear ID when
FLEDGE consent is revoked.

Test: atest
Change-Id: If866ae038cd86581b984d92e16592637db9acd3d
diff --git a/adservices/service-core/java/com/android/adservices/service/consent/ConsentManager.java b/adservices/service-core/java/com/android/adservices/service/consent/ConsentManager.java
index 321cd32..e98754e 100644
--- a/adservices/service-core/java/com/android/adservices/service/consent/ConsentManager.java
+++ b/adservices/service-core/java/com/android/adservices/service/consent/ConsentManager.java
@@ -55,6 +55,7 @@
 import com.android.adservices.service.FlagsFactory;
 import com.android.adservices.service.appsearch.AppSearchConsentManager;
 import com.android.adservices.service.common.BackgroundJobsManager;
+import com.android.adservices.service.common.UserProfileIdManager;
 import com.android.adservices.service.common.feature.PrivacySandboxFeatureType;
 import com.android.adservices.service.measurement.MeasurementImpl;
 import com.android.adservices.service.measurement.WipeoutStatus;
@@ -116,6 +117,7 @@
     private final AdServicesManager mAdServicesManager;
     private final int mConsentSourceOfTruth;
     private final AppSearchConsentManager mAppSearchConsentManager;
+    private final UserProfileIdManager mUserProfileIdManager;
 
     private static final Object LOCK = new Object();
 
@@ -129,6 +131,7 @@
             @NonNull AdServicesManager adServicesManager,
             @NonNull BooleanFileDatastore booleanFileDatastore,
             @NonNull AppSearchConsentManager appSearchConsentManager,
+            @NonNull UserProfileIdManager userProfileIdManager,
             @NonNull Flags flags,
             @Flags.ConsentSourceOfTruth int consentSourceOfTruth) {
         Objects.requireNonNull(topicsWorker);
@@ -137,6 +140,7 @@
         Objects.requireNonNull(customAudienceDao);
         Objects.requireNonNull(appInstallDao);
         Objects.requireNonNull(booleanFileDatastore);
+        Objects.requireNonNull(userProfileIdManager);
 
         if (consentSourceOfTruth != Flags.PPAPI_ONLY
                 && consentSourceOfTruth != Flags.APPSEARCH_ONLY) {
@@ -157,6 +161,7 @@
         mAppInstallDao = appInstallDao;
 
         mAppSearchConsentManager = appSearchConsentManager;
+        mUserProfileIdManager = userProfileIdManager;
         mFlags = flags;
         mConsentSourceOfTruth = consentSourceOfTruth;
     }
@@ -214,6 +219,7 @@
                                     adServicesManager,
                                     datastore,
                                     appSearchConsentManager,
+                                    UserProfileIdManager.getInstance(context),
                                     // TODO(b/260601944): Remove Flag Instance.
                                     FlagsFactory.getFlags(),
                                     consentSourceOfTruth);
@@ -241,6 +247,8 @@
             resetTopicsAndBlockedTopics();
             resetAppsAndBlockedApps();
             resetMeasurement();
+            resetUserProfileId();
+            mUserProfileIdManager.getOrCreateId();
         } catch (IOException e) {
             throw new RuntimeException(ConsentConstants.ERROR_MESSAGE_WHILE_SET_CONTENT, e);
         }
@@ -265,6 +273,7 @@
             resetAppsAndBlockedApps();
             resetMeasurement();
             resetEnrollment();
+            resetUserProfileId();
 
             BackgroundJobsManager.unscheduleAllBackgroundJobs(
                     context.getSystemService(JobScheduler.class));
@@ -295,6 +304,10 @@
         try {
             // reset all state data which should be removed
             resetByApi(apiType);
+
+            if (AdServicesApiType.FLEDGE == apiType) {
+                mUserProfileIdManager.getOrCreateId();
+            }
         } catch (IOException e) {
             throw new RuntimeException(ConsentConstants.ERROR_MESSAGE_WHILE_SET_CONTENT, e);
         }
@@ -1809,6 +1822,7 @@
                 break;
             case FLEDGE:
                 resetAppsAndBlockedApps();
+                resetUserProfileId();
                 break;
             case MEASUREMENTS:
                 resetMeasurement();
@@ -1816,6 +1830,10 @@
         }
     }
 
+    private void resetUserProfileId() {
+        mUserProfileIdManager.deleteId();
+    }
+
     @VisibleForTesting
     static void setConsentToSystemServer(
             @NonNull AdServicesManager adServicesManager, boolean isGiven) {
diff --git a/adservices/tests/unittest/service-core/src/com/android/adservices/service/consent/ConsentManagerTest.java b/adservices/tests/unittest/service-core/src/com/android/adservices/service/consent/ConsentManagerTest.java
index 8899b8c..f06d5bb 100644
--- a/adservices/tests/unittest/service-core/src/com/android/adservices/service/consent/ConsentManagerTest.java
+++ b/adservices/tests/unittest/service-core/src/com/android/adservices/service/consent/ConsentManagerTest.java
@@ -109,6 +109,7 @@
 import com.android.adservices.service.MaintenanceJobService;
 import com.android.adservices.service.appsearch.AppSearchConsentManager;
 import com.android.adservices.service.common.BackgroundJobsManager;
+import com.android.adservices.service.common.UserProfileIdManager;
 import com.android.adservices.service.common.compat.PackageManagerCompatUtils;
 import com.android.adservices.service.common.feature.PrivacySandboxFeatureType;
 import com.android.adservices.service.measurement.DeleteExpiredJobService;
@@ -176,6 +177,7 @@
     @Mock private JobScheduler mJobSchedulerMock;
     @Mock private IAdServicesManager mMockIAdServicesManager;
     @Mock private AppSearchConsentManager mAppSearchConsentManager;
+    @Mock private UserProfileIdManager mUserProfileIdManager;
     private MockitoSession mStaticMockSession = null;
 
     @Before
@@ -600,6 +602,7 @@
         verify(mMeasurementImpl, times(1)).deleteAllMeasurementData(any());
         verify(mCustomAudienceDaoMock).deleteAllCustomAudienceData();
         verify(mAppInstallDaoMock).deleteAllAppInstallData();
+        verify(mUserProfileIdManager).deleteId();
     }
 
     @Test
@@ -617,6 +620,7 @@
         verify(mMeasurementImpl, times(1)).deleteAllMeasurementData(any());
         verify(mCustomAudienceDaoMock).deleteAllCustomAudienceData();
         verifyZeroInteractions(mAppInstallDaoMock);
+        verify(mUserProfileIdManager).deleteId();
     }
 
     @Test
@@ -632,6 +636,8 @@
         verify(mMeasurementImpl, times(1)).deleteAllMeasurementData(any());
         verify(mCustomAudienceDaoMock).deleteAllCustomAudienceData();
         verify(mAppInstallDaoMock).deleteAllAppInstallData();
+        verify(mUserProfileIdManager).deleteId();
+        verify(mUserProfileIdManager).getOrCreateId();
     }
 
     @Test
@@ -648,6 +654,8 @@
         verify(mMeasurementImpl, times(1)).deleteAllMeasurementData(any());
         verify(mCustomAudienceDaoMock).deleteAllCustomAudienceData();
         verifyZeroInteractions(mAppInstallDaoMock);
+        verify(mUserProfileIdManager).deleteId();
+        verify(mUserProfileIdManager).getOrCreateId();
     }
 
     @Test
@@ -2858,6 +2866,7 @@
                         mAdServicesManager,
                         mConsentDatastore,
                         mAppSearchConsentManager,
+                        mUserProfileIdManager,
                         mMockFlags,
                         Flags.PPAPI_ONLY);
         doNothing().when(mBlockedTopicsManager).blockTopic(any());
@@ -2990,6 +2999,40 @@
     }
 
     @Test
+    public void testFledgeConsentIsEnabled_userProfileIdIsClearedThanRecreated()
+            throws RemoteException {
+        ExtendedMockito.doNothing().when(() -> ErrorLogUtil.e(any(), anyInt(), anyInt()));
+        when(mMockFlags.getGaUxFeatureEnabled()).thenReturn(true);
+        boolean isGiven = true;
+        int consentSourceOfTruth = Flags.PPAPI_AND_SYSTEM_SERVER;
+        ConsentManager spyConsentManager =
+                getSpiedConsentManagerForConsentPerApiTesting(
+                        isGiven, consentSourceOfTruth, AdServicesApiType.FLEDGE.toConsentApiType());
+
+        spyConsentManager.enable(mContextSpy, AdServicesApiType.FLEDGE);
+
+        assertThat(spyConsentManager.getConsent(AdServicesApiType.FLEDGE).isGiven()).isTrue();
+        verify(mUserProfileIdManager).deleteId();
+        verify(mUserProfileIdManager).getOrCreateId();
+    }
+
+    @Test
+    public void testFledgeConsentIsDisabled_userProfileIdIsCleared() throws RemoteException {
+        ExtendedMockito.doNothing().when(() -> ErrorLogUtil.e(any(), anyInt(), anyInt()));
+        when(mMockFlags.getGaUxFeatureEnabled()).thenReturn(true);
+        boolean isGiven = false;
+        int consentSourceOfTruth = Flags.PPAPI_AND_SYSTEM_SERVER;
+        ConsentManager spyConsentManager =
+                getSpiedConsentManagerForConsentPerApiTesting(
+                        isGiven, consentSourceOfTruth, AdServicesApiType.FLEDGE.toConsentApiType());
+
+        spyConsentManager.disable(mContextSpy, AdServicesApiType.FLEDGE);
+
+        assertThat(spyConsentManager.getConsent(AdServicesApiType.FLEDGE).isGiven()).isFalse();
+        verify(mUserProfileIdManager).deleteId();
+    }
+
+    @Test
     public void testGetDefaultConsent_AppSearchOnly() throws RemoteException {
         doReturn(true).when(mMockFlags).getEnableAppsearchConsentData();
         int consentSourceOfTruth = Flags.APPSEARCH_ONLY;
@@ -3314,6 +3357,7 @@
                 mAdServicesManager,
                 mConsentDatastore,
                 mAppSearchConsentManager,
+                mUserProfileIdManager,
                 mMockFlags,
                 consentSourceOfTruth);
     }