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 package com.android.server.adservices;
17 
18 import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_MANAGER;
19 import static android.app.adservices.AdServicesManager.AD_SERVICES_SYSTEM_SERVICE;
20 
21 import android.adservices.common.AdServicesPermissions;
22 import android.annotation.NonNull;
23 import android.annotation.RequiresPermission;
24 import android.app.adservices.AdServicesManager;
25 import android.app.adservices.IAdServicesManager;
26 import android.app.adservices.consent.ConsentParcel;
27 import android.app.adservices.topics.TopicParcel;
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.content.pm.PackageInfo;
33 import android.content.pm.PackageManager;
34 import android.content.pm.ResolveInfo;
35 import android.content.pm.VersionedPackage;
36 import android.content.rollback.PackageRollbackInfo;
37 import android.content.rollback.RollbackInfo;
38 import android.content.rollback.RollbackManager;
39 import android.os.Binder;
40 import android.os.Handler;
41 import android.os.HandlerThread;
42 import android.os.ParcelFileDescriptor;
43 import android.os.UserHandle;
44 import android.provider.DeviceConfig;
45 import android.util.ArrayMap;
46 import android.util.Dumpable;
47 
48 import com.android.adservices.service.CommonFlagsConstants;
49 import com.android.internal.annotations.GuardedBy;
50 import com.android.internal.annotations.VisibleForTesting;
51 import com.android.modules.utils.BackgroundThread;
52 import com.android.server.LocalManagerRegistry;
53 import com.android.server.SystemService;
54 import com.android.server.adservices.data.topics.TopicsDao;
55 import com.android.server.adservices.feature.PrivacySandboxFeatureType;
56 import com.android.server.adservices.feature.PrivacySandboxUxCollection;
57 import com.android.server.sdksandbox.SdkSandboxManagerLocal;
58 
59 import java.io.FileDescriptor;
60 import java.io.IOException;
61 import java.io.PrintWriter;
62 import java.util.Arrays;
63 import java.util.List;
64 import java.util.Map;
65 import java.util.Objects;
66 
67 /** @hide */
68 // TODO(b/267667963): Offload methods from binder thread to background thread.
69 public class AdServicesManagerService extends IAdServicesManager.Stub {
70     // The base directory for AdServices System Service.
71     private static final String SYSTEM_DATA = "/data/system/";
72     public static String ADSERVICES_BASE_DIR = SYSTEM_DATA + "adservices";
73     private static final String ERROR_MESSAGE_NOT_PERMITTED_TO_CALL_ADSERVICESMANAGER_API =
74             "Unauthorized caller. Permission to call AdServicesManager API is not granted in System"
75                     + " Server.";
76     private final Object mRegisterReceiverLock = new Object();
77     private final Object mRollbackCheckLock = new Object();
78     private final Object mSetPackageVersionLock = new Object();
79 
80     /**
81      * Broadcast send from the system service to the AdServices module when a package has been
82      * installed/uninstalled. This intent must match the intent defined in the AdServices manifest.
83      */
84     private static final String PACKAGE_CHANGED_BROADCAST =
85             "com.android.adservices.PACKAGE_CHANGED";
86 
87     /** Key for designating the specific action. */
88     private static final String ACTION_KEY = "action";
89 
90     /** Value if the package change was an uninstallation. */
91     private static final String PACKAGE_FULLY_REMOVED = "package_fully_removed";
92 
93     /** Value if the package change was an installation. */
94     private static final String PACKAGE_ADDED = "package_added";
95 
96     /** Value if the package has its data cleared. */
97     private static final String PACKAGE_DATA_CLEARED = "package_data_cleared";
98 
99     private final Context mContext;
100 
101     @GuardedBy("mRegisterReceiverLock")
102     private BroadcastReceiver mSystemServicePackageChangedReceiver;
103 
104     @GuardedBy("mRegisterReceiverLock")
105     private BroadcastReceiver mSystemServiceUserActionReceiver;
106 
107     @GuardedBy("mRegisterReceiverLock")
108     private HandlerThread mHandlerThread;
109 
110     @GuardedBy("mRegisterReceiverLock")
111     private Handler mHandler;
112 
113     @GuardedBy("mSetPackageVersionLock")
114     private int mAdServicesModuleVersion;
115 
116     @GuardedBy("mSetPackageVersionLock")
117     private String mAdServicesModuleName;
118 
119     @GuardedBy("mRollbackCheckLock")
120     private final Map<Integer, VersionedPackage> mAdServicesPackagesRolledBackFrom =
121             new ArrayMap<>();
122 
123     @GuardedBy("mRollbackCheckLock")
124     private final Map<Integer, VersionedPackage> mAdServicesPackagesRolledBackTo = new ArrayMap<>();
125 
126     // This will be triggered when there is a flag change.
127     private final DeviceConfig.OnPropertiesChangedListener mOnFlagsChangedListener =
128             properties -> {
129                 if (!properties.getNamespace().equals(DeviceConfig.NAMESPACE_ADSERVICES)) {
130                     return;
131                 }
132                 registerReceivers();
133                 setAdServicesApexVersion();
134                 setRollbackStatus();
135             };
136 
137     private final UserInstanceManager mUserInstanceManager;
138 
139     @VisibleForTesting
AdServicesManagerService(Context context, UserInstanceManager userInstanceManager)140     AdServicesManagerService(Context context, UserInstanceManager userInstanceManager) {
141         mContext = context;
142         mUserInstanceManager = userInstanceManager;
143 
144         // TODO(b/298635325): use AdServices shared background thread pool instead.
145         DeviceConfig.addOnPropertiesChangedListener(
146                 DeviceConfig.NAMESPACE_ADSERVICES,
147                 BackgroundThread.getExecutor(),
148                 mOnFlagsChangedListener);
149 
150         registerReceivers();
151         setAdServicesApexVersion();
152         setRollbackStatus();
153     }
154 
155     /** @hide */
156     public static final class Lifecycle extends SystemService implements Dumpable {
157         private final AdServicesManagerService mService;
158 
159         /** @hide */
Lifecycle(Context context)160         public Lifecycle(Context context) {
161             this(
162                     context,
163                     new AdServicesManagerService(
164                             context,
165                             new UserInstanceManager(
166                                     TopicsDao.getInstance(context), ADSERVICES_BASE_DIR)));
167         }
168 
169         /** @hide */
170         @VisibleForTesting
Lifecycle(Context context, AdServicesManagerService service)171         public Lifecycle(Context context, AdServicesManagerService service) {
172             super(context);
173             mService = service;
174             LogUtil.d("AdServicesManagerService constructed!");
175         }
176 
177         /** @hide */
178         @Override
onStart()179         public void onStart() {
180             LogUtil.d("AdServicesManagerService started!");
181 
182             boolean published = false;
183 
184             try {
185                 publishBinderService();
186                 published = true;
187             } catch (RuntimeException e) {
188                 LogUtil.w(
189                         e,
190                         "Failed to publish %s service; will piggyback it into SdkSandbox anyways",
191                         AD_SERVICES_SYSTEM_SERVICE);
192             }
193 
194             // TODO(b/282239822): Remove this workaround (and try-catch above) on Android VIC
195 
196             // Register the AdServicesManagerService with the SdkSandboxManagerService.
197             // This is a workaround for b/262282035.
198             // This works since we start the SdkSandboxManagerService before the
199             // AdServicesManagerService in the SystemServer.java
200             SdkSandboxManagerLocal sdkSandboxManagerLocal =
201                     LocalManagerRegistry.getManager(SdkSandboxManagerLocal.class);
202             if (sdkSandboxManagerLocal != null) {
203                 sdkSandboxManagerLocal.registerAdServicesManagerService(mService, published);
204             } else {
205                 throw new IllegalStateException(
206                         "SdkSandboxManagerLocal not found when registering AdServicesManager!");
207             }
208         }
209 
210         // Need to encapsulate call to publishBinderService(...) because:
211         // - Superclass method is protected final (hence it cannot be mocked or extended)
212         // - Underlying method calls ServiceManager.addService(), which is hidden (and hence cannot
213         //   be mocked by our tests)
214         @VisibleForTesting
publishBinderService()215         void publishBinderService() {
216             publishBinderService(AD_SERVICES_SYSTEM_SERVICE, mService);
217         }
218 
219         @Override
getDumpableName()220         public String getDumpableName() {
221             return "AdServices";
222         }
223 
224         @Override
dump(PrintWriter writer, String[] args)225         public void dump(PrintWriter writer, String[] args) {
226             // Dumps the service when it could not be published as a binder service.
227             // Usage: adb shell dumpsys system_server_dumper --name AdServices
228             mService.dump(/* fd= */ null, writer, args);
229         }
230     }
231 
232     @Override
233     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getConsent(@onsentParcel.ConsentApiType int consentApiType)234     public ConsentParcel getConsent(@ConsentParcel.ConsentApiType int consentApiType) {
235         return executeGetter(/* defaultReturn= */
236                 ConsentParcel.createRevokedConsent(consentApiType),
237                 (userId) -> mUserInstanceManager
238                         .getOrCreateUserConsentManagerInstance(userId)
239                         .getConsent(consentApiType));
240     }
241 
242     // Return the User Identifier from the CallingUid.
getUserIdentifierFromBinderCallingUid()243     private int getUserIdentifierFromBinderCallingUid() {
244         return UserHandle.getUserHandleForUid(Binder.getCallingUid()).getIdentifier();
245     }
246 
247     @Override
248     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setConsent(ConsentParcel consentParcel)249     public void setConsent(ConsentParcel consentParcel) {
250         enforceAdServicesManagerPermission();
251 
252         Objects.requireNonNull(consentParcel);
253 
254         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
255         LogUtil.v("setConsent() for User Identifier %d", userIdentifier);
256         try {
257             mUserInstanceManager
258                     .getOrCreateUserConsentManagerInstance(userIdentifier)
259                     .setConsent(consentParcel);
260         } catch (IOException e) {
261             LogUtil.e(e, "Failed to persist the consent.");
262         }
263     }
264 
265     @Override
266     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordNotificationDisplayed(boolean wasNotificationDisplayed)267     public void recordNotificationDisplayed(boolean wasNotificationDisplayed) {
268         enforceAdServicesManagerPermission();
269 
270         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
271         LogUtil.v("recordNotificationDisplayed() for User Identifier %d", userIdentifier);
272         try {
273             mUserInstanceManager
274                     .getOrCreateUserConsentManagerInstance(userIdentifier)
275                     .recordNotificationDisplayed(wasNotificationDisplayed);
276         } catch (IOException e) {
277             LogUtil.e(e, "Failed to Record Notification Displayed.");
278         }
279     }
280 
281     /**
282      * Record blocked topics.
283      *
284      * @param blockedTopicParcels the blocked topics to record
285      */
286     @Override
287     @RequiresPermission(ACCESS_ADSERVICES_MANAGER)
recordBlockedTopic(@onNull List<TopicParcel> blockedTopicParcels)288     public void recordBlockedTopic(@NonNull List<TopicParcel> blockedTopicParcels) {
289         enforceAdServicesManagerPermission();
290 
291         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
292         LogUtil.v("recordBlockedTopic() for User Identifier %d", userIdentifier);
293         mUserInstanceManager
294                 .getOrCreateUserBlockedTopicsManagerInstance(userIdentifier)
295                 .recordBlockedTopic(blockedTopicParcels);
296     }
297 
298     /**
299      * Remove a blocked topic.
300      *
301      * @param blockedTopicParcel the blocked topic to remove
302      */
303     @Override
304     @RequiresPermission(ACCESS_ADSERVICES_MANAGER)
removeBlockedTopic(@onNull TopicParcel blockedTopicParcel)305     public void removeBlockedTopic(@NonNull TopicParcel blockedTopicParcel) {
306         enforceAdServicesManagerPermission();
307 
308         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
309         LogUtil.v("removeBlockedTopic() for User Identifier %d", userIdentifier);
310         mUserInstanceManager
311                 .getOrCreateUserBlockedTopicsManagerInstance(userIdentifier)
312                 .removeBlockedTopic(blockedTopicParcel);
313     }
314 
315     /**
316      * Get all blocked topics.
317      *
318      * @return a {@code List} of all blocked topics.
319      */
320     @Override
321     @RequiresPermission(ACCESS_ADSERVICES_MANAGER)
retrieveAllBlockedTopics()322     public List<TopicParcel> retrieveAllBlockedTopics() {
323         return executeGetter(/* defaultReturn= */ List.of(),
324                 (userId) -> mUserInstanceManager
325                         .getOrCreateUserBlockedTopicsManagerInstance(userId)
326                         .retrieveAllBlockedTopics());
327     }
328 
329     /** Clear all Blocked Topics */
330     @Override
331     @RequiresPermission(ACCESS_ADSERVICES_MANAGER)
clearAllBlockedTopics()332     public void clearAllBlockedTopics() {
333         enforceAdServicesManagerPermission();
334 
335         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
336         LogUtil.v("clearAllBlockedTopics() for User Identifier %d", userIdentifier);
337         mUserInstanceManager
338                 .getOrCreateUserBlockedTopicsManagerInstance(userIdentifier)
339                 .clearAllBlockedTopics();
340     }
341 
342     @Override
343     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
wasNotificationDisplayed()344     public boolean wasNotificationDisplayed() {
345         return executeGetter(/* defaultReturn= */ false,
346                 (userId) -> mUserInstanceManager
347                         .getOrCreateUserConsentManagerInstance(userId)
348                         .wasNotificationDisplayed());
349     }
350 
351     @Override
352     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordGaUxNotificationDisplayed(boolean wasNotificationDisplayed)353     public void recordGaUxNotificationDisplayed(boolean wasNotificationDisplayed) {
354         enforceAdServicesManagerPermission();
355 
356         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
357         LogUtil.v("recordGaUxNotificationDisplayed() for User Identifier %d", userIdentifier);
358         try {
359             mUserInstanceManager
360                     .getOrCreateUserConsentManagerInstance(userIdentifier)
361                     .recordGaUxNotificationDisplayed(wasNotificationDisplayed);
362         } catch (IOException e) {
363             LogUtil.e(e, "Fail to Record GA UX Notification Displayed.");
364         }
365     }
366 
367     @Override
368     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordDefaultConsent(boolean defaultConsent)369     public void recordDefaultConsent(boolean defaultConsent) {
370         enforceAdServicesManagerPermission();
371 
372         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
373         LogUtil.v("recordDefaultConsent() for User Identifier %d", userIdentifier);
374         try {
375             mUserInstanceManager
376                     .getOrCreateUserConsentManagerInstance(userIdentifier)
377                     .recordDefaultConsent(defaultConsent);
378         } catch (IOException e) {
379             LogUtil.e(e, "Fail to record default consent: " + e.getMessage());
380         }
381     }
382 
383     @Override
384     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordTopicsDefaultConsent(boolean defaultConsent)385     public void recordTopicsDefaultConsent(boolean defaultConsent) {
386         enforceAdServicesManagerPermission();
387 
388         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
389         LogUtil.v("recordTopicsDefaultConsent() for User Identifier %d", userIdentifier);
390         try {
391             mUserInstanceManager
392                     .getOrCreateUserConsentManagerInstance(userIdentifier)
393                     .recordTopicsDefaultConsent(defaultConsent);
394         } catch (IOException e) {
395             LogUtil.e(e, "Fail to record topics default consent: " + e.getMessage());
396         }
397     }
398 
399     @Override
400     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordFledgeDefaultConsent(boolean defaultConsent)401     public void recordFledgeDefaultConsent(boolean defaultConsent) {
402         enforceAdServicesManagerPermission();
403 
404         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
405         LogUtil.v("recordFledgeDefaultConsent() for User Identifier %d", userIdentifier);
406         try {
407             mUserInstanceManager
408                     .getOrCreateUserConsentManagerInstance(userIdentifier)
409                     .recordFledgeDefaultConsent(defaultConsent);
410         } catch (IOException e) {
411             LogUtil.e(e, "Fail to record fledge default consent: " + e.getMessage());
412         }
413     }
414 
415     @Override
416     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordMeasurementDefaultConsent(boolean defaultConsent)417     public void recordMeasurementDefaultConsent(boolean defaultConsent) {
418         enforceAdServicesManagerPermission();
419 
420         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
421         LogUtil.v("recordMeasurementDefaultConsent() for User Identifier %d", userIdentifier);
422         try {
423             mUserInstanceManager
424                     .getOrCreateUserConsentManagerInstance(userIdentifier)
425                     .recordMeasurementDefaultConsent(defaultConsent);
426         } catch (IOException e) {
427             LogUtil.e(e, "Fail to record measurement default consent: " + e.getMessage());
428         }
429     }
430 
431     @Override
432     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordDefaultAdIdState(boolean defaultAdIdState)433     public void recordDefaultAdIdState(boolean defaultAdIdState) {
434         enforceAdServicesManagerPermission();
435 
436         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
437         LogUtil.v("recordDefaultAdIdState() for User Identifier %d", userIdentifier);
438         try {
439             mUserInstanceManager
440                     .getOrCreateUserConsentManagerInstance(userIdentifier)
441                     .recordDefaultAdIdState(defaultAdIdState);
442         } catch (IOException e) {
443             LogUtil.e(e, "Fail to record default AdId state: " + e.getMessage());
444         }
445     }
446 
447     @Override
448     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordUserManualInteractionWithConsent(int interaction)449     public void recordUserManualInteractionWithConsent(int interaction) {
450         enforceAdServicesManagerPermission();
451 
452         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
453         LogUtil.v(
454                 "recordUserManualInteractionWithConsent() for User Identifier %d, interaction %d",
455                 userIdentifier, interaction);
456         try {
457             mUserInstanceManager
458                     .getOrCreateUserConsentManagerInstance(userIdentifier)
459                     .recordUserManualInteractionWithConsent(interaction);
460         } catch (IOException e) {
461             LogUtil.e(
462                     e, "Fail to record default manual interaction with consent: " + e.getMessage());
463         }
464     }
465 
466     @Override
467     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getTopicsDefaultConsent()468     public boolean getTopicsDefaultConsent() {
469         return executeGetter(/* defaultReturn= */ false,
470                 (userId) -> mUserInstanceManager
471                         .getOrCreateUserConsentManagerInstance(userId)
472                         .getTopicsDefaultConsent());
473     }
474 
475     @Override
476     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getFledgeDefaultConsent()477     public boolean getFledgeDefaultConsent() {
478         return executeGetter(/* defaultReturn= */ false,
479                 (userId) -> mUserInstanceManager
480                         .getOrCreateUserConsentManagerInstance(userId)
481                         .getFledgeDefaultConsent());
482     }
483 
484     @Override
485     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getMeasurementDefaultConsent()486     public boolean getMeasurementDefaultConsent() {
487         return executeGetter(/* defaultReturn= */ false,
488                 (userId) -> mUserInstanceManager
489                         .getOrCreateUserConsentManagerInstance(userId)
490                         .getMeasurementDefaultConsent());
491     }
492 
493     @Override
494     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getDefaultAdIdState()495     public boolean getDefaultAdIdState() {
496         return executeGetter(/* defaultReturn= */ false,
497                 (userId) -> mUserInstanceManager
498                         .getOrCreateUserConsentManagerInstance(userId)
499                         .getDefaultAdIdState());
500     }
501 
502     @Override
503     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getUserManualInteractionWithConsent()504     public int getUserManualInteractionWithConsent() {
505         return executeGetter(/* defaultReturn= */ 0,
506                 (userId) -> mUserInstanceManager
507                         .getOrCreateUserConsentManagerInstance(userId)
508                         .getUserManualInteractionWithConsent());
509     }
510 
511     @Override
512     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
wasGaUxNotificationDisplayed()513     public boolean wasGaUxNotificationDisplayed() {
514         return executeGetter(/* defaultReturn= */ false,
515                 (userId) -> mUserInstanceManager
516                         .getOrCreateUserConsentManagerInstance(userId)
517                         .wasGaUxNotificationDisplayed());
518     }
519 
520     @Override
521     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordPasNotificationDisplayed(boolean wasNotificationDisplayed)522     public void recordPasNotificationDisplayed(boolean wasNotificationDisplayed) {
523         enforceAdServicesManagerPermission();
524 
525         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
526         LogUtil.v("recordPasNotificationDisplayed() for User Identifier %d", userIdentifier);
527         try {
528             mUserInstanceManager
529                     .getOrCreateUserConsentManagerInstance(userIdentifier)
530                     .recordPasNotificationDisplayed(wasNotificationDisplayed);
531         } catch (IOException e) {
532             LogUtil.e(e, "Fail to Record PAS Notification Displayed.");
533         }
534     }
535 
536     @Override
537     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
wasPasNotificationDisplayed()538     public boolean wasPasNotificationDisplayed() {
539         return executeGetter(
540                 /* defaultReturn= */ true,
541                 (userId) ->
542                         mUserInstanceManager
543                                 .getOrCreateUserConsentManagerInstance(userId)
544                                 .wasPasNotificationDisplayed());
545     }
546 
547     @Override
548     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordPasNotificationOpened(boolean wasNotificationOpened)549     public void recordPasNotificationOpened(boolean wasNotificationOpened) {
550         enforceAdServicesManagerPermission();
551 
552         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
553         LogUtil.v("recordPasNotificationOpened() for User Identifier %d", userIdentifier);
554         try {
555             mUserInstanceManager
556                     .getOrCreateUserConsentManagerInstance(userIdentifier)
557                     .recordPasNotificationOpened(wasNotificationOpened);
558         } catch (IOException e) {
559             LogUtil.e(e, "Fail to Record PAS Notification Opened.");
560         }
561     }
562 
563     @Override
564     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
wasPasNotificationOpened()565     public boolean wasPasNotificationOpened() {
566         return executeGetter(
567                 /* defaultReturn= */ true,
568                 (userId) ->
569                         mUserInstanceManager
570                                 .getOrCreateUserConsentManagerInstance(userId)
571                                 .wasPasNotificationOpened());
572     }
573 
574     /** retrieves the default consent of a user. */
575     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getDefaultConsent()576     public boolean getDefaultConsent() {
577         return executeGetter(/* defaultReturn= */ false,
578                 (userId) -> mUserInstanceManager
579                         .getOrCreateUserConsentManagerInstance(userId)
580                         .getDefaultConsent());
581     }
582 
583     /** Get the currently running privacy sandbox feature on device. */
584     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getCurrentPrivacySandboxFeature()585     public String getCurrentPrivacySandboxFeature() {
586         enforceAdServicesManagerPermission();
587 
588         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
589         LogUtil.v("getCurrentPrivacySandboxFeature() for User Identifier %d", userIdentifier);
590         try {
591             for (PrivacySandboxFeatureType featureType : PrivacySandboxFeatureType.values()) {
592                 if (mUserInstanceManager
593                         .getOrCreateUserConsentManagerInstance(userIdentifier)
594                         .isPrivacySandboxFeatureEnabled(featureType)) {
595                     return featureType.name();
596                 }
597             }
598         } catch (IOException e) {
599             LogUtil.e(e, "Fail to get the privacy sandbox feature state: " + e.getMessage());
600         }
601         return PrivacySandboxFeatureType.PRIVACY_SANDBOX_UNSUPPORTED.name();
602     }
603 
604     /** Set the currently running privacy sandbox feature on device. */
605     @Override
606     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setCurrentPrivacySandboxFeature(String featureType)607     public void setCurrentPrivacySandboxFeature(String featureType) {
608         enforceAdServicesManagerPermission();
609 
610         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
611         LogUtil.v("setCurrentPrivacySandboxFeature() for User Identifier %d", userIdentifier);
612         try {
613             mUserInstanceManager
614                     .getOrCreateUserConsentManagerInstance(userIdentifier)
615                     .setCurrentPrivacySandboxFeature(featureType);
616         } catch (IOException e) {
617             LogUtil.e(e, "Fail to set current privacy sandbox feature: " + e.getMessage());
618         }
619     }
620 
621     @Override
622     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getKnownAppsWithConsent(@onNull List<String> installedPackages)623     public List<String> getKnownAppsWithConsent(@NonNull List<String> installedPackages) {
624         return executeGetter(/* defaultReturn= */ List.of(),
625                 (userId) -> mUserInstanceManager
626                         .getOrCreateUserAppConsentManagerInstance(userId)
627                         .getKnownAppsWithConsent(installedPackages));
628     }
629 
630     @Override
631     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getAppsWithRevokedConsent(@onNull List<String> installedPackages)632     public List<String> getAppsWithRevokedConsent(@NonNull List<String> installedPackages) {
633         return executeGetter(/* defaultReturn= */ List.of(),
634                 (userId) -> mUserInstanceManager
635                         .getOrCreateUserAppConsentManagerInstance(userId)
636                         .getAppsWithRevokedConsent(installedPackages));
637     }
638 
639     @Override
640     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setConsentForApp( @onNull String packageName, int packageUid, boolean isConsentRevoked)641     public void setConsentForApp(
642             @NonNull String packageName, int packageUid, boolean isConsentRevoked) {
643         enforceAdServicesManagerPermission();
644 
645         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
646 
647         LogUtil.v(
648                 "setConsentForApp() for User Identifier %d, package name %s, and package uid %d to"
649                         + " %s.",
650                 userIdentifier, packageName, packageUid, isConsentRevoked);
651         try {
652             mUserInstanceManager
653                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
654                     .setConsentForApp(packageName, packageUid, isConsentRevoked);
655         } catch (IOException e) {
656             LogUtil.e(
657                     e,
658                     "Failed to setConsentForApp() for User Identifier %d, package name %s, and"
659                             + " package uid %d to %s.",
660                     userIdentifier,
661                     packageName,
662                     packageUid,
663                     isConsentRevoked);
664         }
665     }
666 
667     @Override
668     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
clearKnownAppsWithConsent()669     public void clearKnownAppsWithConsent() {
670         enforceAdServicesManagerPermission();
671 
672         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
673         LogUtil.v("clearKnownAppsWithConsent() for user identifier %d.", userIdentifier);
674         try {
675             mUserInstanceManager
676                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
677                     .clearKnownAppsWithConsent();
678         } catch (IOException e) {
679             LogUtil.e(
680                     e,
681                     "Failed to clearKnownAppsWithConsent() for user identifier %d",
682                     userIdentifier);
683         }
684     }
685 
686     @Override
687     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
clearAllAppConsentData()688     public void clearAllAppConsentData() {
689         enforceAdServicesManagerPermission();
690 
691         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
692         LogUtil.v("clearAllAppConsentData() for user identifier %d.", userIdentifier);
693 
694         try {
695             mUserInstanceManager
696                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
697                     .clearAllAppConsentData();
698         } catch (IOException e) {
699             LogUtil.e(
700                     e, "Failed to clearAllAppConsentData() for user identifier %d", userIdentifier);
701         }
702     }
703 
704     @Override
705     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isConsentRevokedForApp(@onNull String packageName, int packageUid)706     public boolean isConsentRevokedForApp(@NonNull String packageName, int packageUid)
707             throws IllegalArgumentException {
708         enforceAdServicesManagerPermission();
709 
710         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
711         LogUtil.v(
712                 "isConsentRevokedForApp() for user identifier %d, package name %s, and package uid"
713                         + " %d.",
714                 userIdentifier, packageName, packageUid);
715         try {
716             return mUserInstanceManager
717                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
718                     .isConsentRevokedForApp(packageName, packageUid);
719         } catch (IOException e) {
720             LogUtil.e(
721                     e,
722                     "Failed to call isConsentRevokedForApp() for user identifier %d, package name"
723                             + " %s, and package uid %d.",
724                     userIdentifier,
725                     packageName,
726                     packageUid);
727             return true;
728         }
729     }
730 
731     @Override
732     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setConsentForAppIfNew( @onNull String packageName, int packageUid, boolean isConsentRevoked)733     public boolean setConsentForAppIfNew(
734             @NonNull String packageName, int packageUid, boolean isConsentRevoked)
735             throws IllegalArgumentException {
736         enforceAdServicesManagerPermission();
737 
738         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
739         LogUtil.v(
740                 "setConsentForAppIfNew() for user identifier %d, package name"
741                         + " %s, and package uid %d to %s.",
742                 userIdentifier, packageName, packageUid, isConsentRevoked);
743         try {
744             return mUserInstanceManager
745                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
746                     .setConsentForAppIfNew(packageName, packageUid, isConsentRevoked);
747         } catch (IOException e) {
748             LogUtil.e(
749                     e,
750                     "Failed to setConsentForAppIfNew() for user identifier %d, package name"
751                             + " %s, and package uid %d to %s.",
752                     userIdentifier,
753                     packageName,
754                     packageUid,
755                     isConsentRevoked);
756             return true;
757         }
758     }
759 
760     @Override
761     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
clearConsentForUninstalledApp(@onNull String packageName, int packageUid)762     public void clearConsentForUninstalledApp(@NonNull String packageName, int packageUid) {
763         enforceAdServicesManagerPermission();
764 
765         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
766         LogUtil.v(
767                 "clearConsentForUninstalledApp() for user identifier %d, package name"
768                         + " %s, and package uid %d.",
769                 userIdentifier, packageName, packageUid);
770         try {
771             mUserInstanceManager
772                     .getOrCreateUserAppConsentManagerInstance(userIdentifier)
773                     .clearConsentForUninstalledApp(packageName, packageUid);
774         } catch (IOException e) {
775             LogUtil.e(
776                     e,
777                     "Failed to clearConsentForUninstalledApp() for user identifier %d, package name"
778                             + " %s, and package uid %d.",
779                     userIdentifier,
780                     packageName,
781                     packageUid);
782         }
783     }
784 
785     @Override
786     @RequiresPermission(android.Manifest.permission.DUMP)
dump(FileDescriptor fd, PrintWriter pw, String[] args)787     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
788         mContext.enforceCallingPermission(android.Manifest.permission.DUMP, /* message= */ null);
789         synchronized (mSetPackageVersionLock) {
790             pw.printf("mAdServicesModuleName: %s\n", mAdServicesModuleName);
791             pw.printf("mAdServicesModuleVersion: %d\n", mAdServicesModuleVersion);
792         }
793         synchronized (mRegisterReceiverLock) {
794             pw.printf("mHandlerThread: %s\n", mHandlerThread);
795         }
796         synchronized (mRollbackCheckLock) {
797             pw.printf("mAdServicesPackagesRolledBackFrom: %s\n", mAdServicesPackagesRolledBackFrom);
798             pw.printf("mAdServicesPackagesRolledBackTo: %s\n", mAdServicesPackagesRolledBackTo);
799         }
800         pw.printf("ShellCmd enabled: %b\n", isShellCmdEnabled());
801         mUserInstanceManager.dump(pw, args);
802     }
803 
isShellCmdEnabled()804     private static boolean isShellCmdEnabled() {
805         return DebugFlags.getInstance().getAdServicesShellCommandEnabled();
806     }
807 
808     @Override
handleShellCommand( ParcelFileDescriptor in, ParcelFileDescriptor out, ParcelFileDescriptor err, String[] args)809     public int handleShellCommand(
810             ParcelFileDescriptor in,
811             ParcelFileDescriptor out,
812             ParcelFileDescriptor err,
813             String[] args) {
814 
815         if (!isShellCmdEnabled()) {
816             LogUtil.d(
817                     "handleShellCommand(%s): disabled by flag %s",
818                     Arrays.toString(args),
819                     CommonFlagsConstants.KEY_ADSERVICES_SHELL_COMMAND_ENABLED);
820             return super.handleShellCommand(in, out, err, args);
821         }
822 
823         LogUtil.v("Executing shell cmd: %s", Arrays.toString(args));
824         return new AdServicesShellCommand(mContext)
825                 .exec(
826                         this,
827                         in.getFileDescriptor(),
828                         out.getFileDescriptor(),
829                         err.getFileDescriptor(),
830                         args);
831     }
832 
833     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
recordAdServicesDeletionOccurred( @dServicesManager.DeletionApiType int deletionType)834     public void recordAdServicesDeletionOccurred(
835             @AdServicesManager.DeletionApiType int deletionType) {
836         enforceAdServicesManagerPermission();
837 
838         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
839         try {
840             LogUtil.v(
841                     "recordAdServicesDeletionOccurred() for user identifier %d, api type %d",
842                     userIdentifier, deletionType);
843             mUserInstanceManager
844                     .getOrCreateUserRollbackHandlingManagerInstance(
845                             userIdentifier, getAdServicesApexVersion())
846                     .recordAdServicesDataDeletion(deletionType);
847         } catch (IOException e) {
848             LogUtil.e(e, "Failed to persist the deletion status.");
849         }
850     }
851 
needsToHandleRollbackReconciliation( @dServicesManager.DeletionApiType int deletionType)852     public boolean needsToHandleRollbackReconciliation(
853             @AdServicesManager.DeletionApiType int deletionType) {
854         // Check if there was at least one rollback of the AdServices module.
855         if (getAdServicesPackagesRolledBackFrom().isEmpty()) {
856             return false;
857         }
858 
859         // Check if the deletion bit is set.
860         if (!hasAdServicesDeletionOccurred(deletionType)) {
861             return false;
862         }
863 
864         // For each rollback, check if the rolled back from version matches the previously stored
865         // version and the rolled back to version matches the current version.
866         int previousStoredVersion = getPreviousStoredVersion(deletionType);
867         for (Integer rollbackId : getAdServicesPackagesRolledBackFrom().keySet()) {
868             if (getAdServicesPackagesRolledBackFrom().get(rollbackId).getLongVersionCode()
869                             == previousStoredVersion
870                     && getAdServicesPackagesRolledBackTo().get(rollbackId).getLongVersionCode()
871                             == getAdServicesApexVersion()) {
872                 resetAdServicesDeletionOccurred(deletionType);
873                 return true;
874             }
875         }
876 
877         // None of the stored rollbacks match the versions.
878         return false;
879     }
880 
881     @VisibleForTesting
hasAdServicesDeletionOccurred(@dServicesManager.DeletionApiType int deletionType)882     boolean hasAdServicesDeletionOccurred(@AdServicesManager.DeletionApiType int deletionType) {
883         return executeGetter(/* defaultReturn= */ false,
884                 (userId) -> mUserInstanceManager.getOrCreateUserRollbackHandlingManagerInstance(
885                                 userId, getAdServicesApexVersion())
886                         .wasAdServicesDataDeleted(deletionType));
887     }
888 
889     @VisibleForTesting
resetAdServicesDeletionOccurred(@dServicesManager.DeletionApiType int deletionType)890     void resetAdServicesDeletionOccurred(@AdServicesManager.DeletionApiType int deletionType) {
891         enforceAdServicesManagerPermission();
892 
893         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
894         try {
895             LogUtil.v("resetMeasurementDeletionOccurred() for user identifier %d", userIdentifier);
896             mUserInstanceManager
897                     .getOrCreateUserRollbackHandlingManagerInstance(
898                             userIdentifier, getAdServicesApexVersion())
899                     .resetAdServicesDataDeletion(deletionType);
900         } catch (IOException e) {
901             LogUtil.e(e, "Failed to remove the fmeasurement deletion status.");
902         }
903     }
904 
905     @VisibleForTesting
getPreviousStoredVersion(@dServicesManager.DeletionApiType int deletionType)906     int getPreviousStoredVersion(@AdServicesManager.DeletionApiType int deletionType) {
907         return executeGetter(/* defaultReturn= */ 0,
908                 (userId) -> mUserInstanceManager.getOrCreateUserRollbackHandlingManagerInstance(
909                                 userId, getAdServicesApexVersion())
910                         .getPreviousStoredVersion(deletionType));
911     }
912 
913     @VisibleForTesting
registerReceivers()914     void registerReceivers() {
915         // There could be race condition between registerReceivers call
916         // in the AdServicesManagerService constructor and the mOnFlagsChangedListener.
917         synchronized (mRegisterReceiverLock) {
918             if (!FlagsFactory.getFlags().getAdServicesSystemServiceEnabled()) {
919                 LogUtil.d("AdServicesSystemServiceEnabled is FALSE.");
920                 // If there is a SystemServicePackageChangeReceiver, unregister it.
921                 if (mSystemServicePackageChangedReceiver != null) {
922                     LogUtil.d("Unregistering the existing SystemServicePackageChangeReceiver");
923                     mContext.unregisterReceiver(mSystemServicePackageChangedReceiver);
924                     mSystemServicePackageChangedReceiver = null;
925                 }
926 
927                 // If there is a SystemServiceUserActionReceiver, unregister it.
928                 if (mSystemServiceUserActionReceiver != null) {
929                     LogUtil.d("Unregistering the existing SystemServiceUserActionReceiver");
930                     mContext.unregisterReceiver(mSystemServiceUserActionReceiver);
931                     mSystemServiceUserActionReceiver = null;
932                 }
933 
934                 if (mHandler != null) {
935                     mHandlerThread.quitSafely();
936                     mHandler = null;
937                 }
938                 return;
939             }
940 
941             // Start the handler thread.
942             if (mHandler == null) {
943                 mHandlerThread = new HandlerThread("AdServicesManagerServiceHandler");
944                 mHandlerThread.start();
945                 mHandler = new Handler(mHandlerThread.getLooper());
946             }
947             registerPackagedChangedBroadcastReceiversLocked();
948             registerUserActionBroadcastReceiverLocked();
949         }
950     }
951 
952     @VisibleForTesting
953     /**
954      * Stores the AdServices module version locally. Users other than the main user do not have the
955      * permission to get the version through the PackageManager, so we have to get the version when
956      * the AdServices system service starts.
957      */
setAdServicesApexVersion()958     void setAdServicesApexVersion() {
959         synchronized (mSetPackageVersionLock) {
960             if (!FlagsFactory.getFlags().getAdServicesSystemServiceEnabled()) {
961                 LogUtil.d("AdServicesSystemServiceEnabled is FALSE.");
962                 return;
963             }
964 
965             PackageManager packageManager = mContext.getPackageManager();
966 
967             List<PackageInfo> installedPackages =
968                     packageManager.getInstalledPackages(
969                             PackageManager.PackageInfoFlags.of(PackageManager.MATCH_APEX));
970 
971             installedPackages.forEach(
972                     packageInfo -> {
973                         if (packageInfo.packageName.contains("adservices") && packageInfo.isApex) {
974                             mAdServicesModuleName = packageInfo.packageName;
975                             mAdServicesModuleVersion = (int) packageInfo.getLongVersionCode();
976                         }
977                     });
978         }
979     }
980 
981     @VisibleForTesting
getAdServicesApexVersion()982     int getAdServicesApexVersion() {
983         return mAdServicesModuleVersion;
984     }
985 
986     @VisibleForTesting
987     /** Checks the RollbackManager to see the rollback status of the AdServices module. */
setRollbackStatus()988     void setRollbackStatus() {
989         synchronized (mRollbackCheckLock) {
990             if (!FlagsFactory.getFlags().getAdServicesSystemServiceEnabled()) {
991                 LogUtil.d("AdServicesSystemServiceEnabled is FALSE.");
992                 resetRollbackArraysRCLocked();
993                 return;
994             }
995 
996             RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
997             if (rollbackManager == null) {
998                 LogUtil.d("Failed to get the RollbackManager service.");
999                 resetRollbackArraysRCLocked();
1000                 return;
1001             }
1002             List<RollbackInfo> recentlyCommittedRollbacks =
1003                     rollbackManager.getRecentlyCommittedRollbacks();
1004 
1005             for (RollbackInfo rollbackInfo : recentlyCommittedRollbacks) {
1006                 for (PackageRollbackInfo packageRollbackInfo : rollbackInfo.getPackages()) {
1007                     if (packageRollbackInfo.getPackageName().equals(mAdServicesModuleName)) {
1008                         mAdServicesPackagesRolledBackFrom.put(
1009                                 rollbackInfo.getRollbackId(),
1010                                 packageRollbackInfo.getVersionRolledBackFrom());
1011                         mAdServicesPackagesRolledBackTo.put(
1012                                 rollbackInfo.getRollbackId(),
1013                                 packageRollbackInfo.getVersionRolledBackTo());
1014                         LogUtil.d(
1015                                 "Rollback of AdServices module occurred, "
1016                                         + "from version %d to version %d",
1017                                 packageRollbackInfo.getVersionRolledBackFrom().getLongVersionCode(),
1018                                 packageRollbackInfo.getVersionRolledBackTo().getLongVersionCode());
1019                     }
1020                 }
1021             }
1022         }
1023     }
1024 
1025     @GuardedBy("mRollbackCheckLock")
resetRollbackArraysRCLocked()1026     private void resetRollbackArraysRCLocked() {
1027         mAdServicesPackagesRolledBackFrom.clear();
1028         mAdServicesPackagesRolledBackTo.clear();
1029     }
1030 
1031     @VisibleForTesting
getAdServicesPackagesRolledBackFrom()1032     Map<Integer, VersionedPackage> getAdServicesPackagesRolledBackFrom() {
1033         return mAdServicesPackagesRolledBackFrom;
1034     }
1035 
1036     @VisibleForTesting
getAdServicesPackagesRolledBackTo()1037     Map<Integer, VersionedPackage> getAdServicesPackagesRolledBackTo() {
1038         return mAdServicesPackagesRolledBackTo;
1039     }
1040 
1041     /**
1042      * Registers a receiver for any broadcasts related to user profile removal for all users on the
1043      * device at boot up. After receiving the broadcast, we delete consent manager instance and
1044      * remove the user related data.
1045      */
registerUserActionBroadcastReceiverLocked()1046     private void registerUserActionBroadcastReceiverLocked() {
1047         if (mSystemServiceUserActionReceiver != null) {
1048             // We already register the receiver.
1049             LogUtil.d("SystemServiceUserActionReceiver is already registered.");
1050             return;
1051         }
1052         mSystemServiceUserActionReceiver =
1053                 new BroadcastReceiver() {
1054                     @Override
1055                     public void onReceive(Context context, Intent intent) {
1056                         mHandler.post(() -> onUserRemoved(intent));
1057                     }
1058                 };
1059         mContext.registerReceiverForAllUsers(
1060                 mSystemServiceUserActionReceiver,
1061                 new IntentFilter(Intent.ACTION_USER_REMOVED),
1062                 /* broadcastPermission= */ null,
1063                 mHandler);
1064         LogUtil.d("SystemServiceUserActionReceiver registered.");
1065     }
1066 
1067     /** Deletes the user instance and remove the user consent related data. */
1068     @VisibleForTesting
onUserRemoved(@onNull Intent intent)1069     void onUserRemoved(@NonNull Intent intent) {
1070         Objects.requireNonNull(intent);
1071         if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) {
1072             UserHandle userHandle = intent.getParcelableExtra(Intent.EXTRA_USER, UserHandle.class);
1073             if (userHandle == null) {
1074                 LogUtil.e("Extra " + Intent.EXTRA_USER + " is missing in the intent: " + intent);
1075                 return;
1076             }
1077             LogUtil.d("Deleting user instance with user id: " + userHandle.getIdentifier());
1078             try {
1079                 mUserInstanceManager.deleteUserInstance(userHandle.getIdentifier());
1080             } catch (Exception e) {
1081                 LogUtil.e(e, "Failed to delete the consent manager directory");
1082             }
1083         }
1084     }
1085 
1086     /**
1087      * Registers a receiver for any broadcasts regarding changes to any packages for all users on
1088      * the device at boot up. After receiving the broadcast, send an explicit broadcast to the
1089      * AdServices module as that user.
1090      */
registerPackagedChangedBroadcastReceiversLocked()1091     private void registerPackagedChangedBroadcastReceiversLocked() {
1092         if (mSystemServicePackageChangedReceiver != null) {
1093             // We already register the receiver.
1094             LogUtil.d("SystemServicePackageChangedReceiver is already registered.");
1095             return;
1096         }
1097 
1098         final IntentFilter packageChangedIntentFilter = new IntentFilter();
1099         packageChangedIntentFilter.addAction(Intent.ACTION_PACKAGE_FULLY_REMOVED);
1100         packageChangedIntentFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
1101         packageChangedIntentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
1102         packageChangedIntentFilter.addDataScheme("package");
1103 
1104         mSystemServicePackageChangedReceiver =
1105                 new BroadcastReceiver() {
1106                     @Override
1107                     public void onReceive(Context context, Intent intent) {
1108                         UserHandle user = getSendingUser();
1109                         mHandler.post(() -> onPackageChange(intent, user));
1110                     }
1111                 };
1112         mContext.registerReceiverForAllUsers(
1113                 mSystemServicePackageChangedReceiver,
1114                 packageChangedIntentFilter,
1115                 /* broadcastPermission */ null,
1116                 mHandler);
1117         LogUtil.d("Package changed broadcast receivers registered.");
1118     }
1119 
1120     /** Sends an explicit broadcast to the AdServices module when a package change occurs. */
1121     @VisibleForTesting
onPackageChange(Intent intent, UserHandle user)1122     public void onPackageChange(Intent intent, UserHandle user) {
1123         Intent explicitBroadcast = new Intent();
1124         explicitBroadcast.setAction(PACKAGE_CHANGED_BROADCAST);
1125         explicitBroadcast.setData(intent.getData());
1126 
1127         final Intent i = new Intent(PACKAGE_CHANGED_BROADCAST);
1128         final List<ResolveInfo> resolveInfo =
1129                 mContext.getPackageManager()
1130                         .queryBroadcastReceiversAsUser(
1131                                 i,
1132                                 PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
1133                                 user);
1134         if (resolveInfo != null && !resolveInfo.isEmpty()) {
1135             for (ResolveInfo info : resolveInfo) {
1136                 explicitBroadcast.setClassName(
1137                         info.activityInfo.packageName, info.activityInfo.name);
1138                 int uidChanged = intent.getIntExtra(Intent.EXTRA_UID, -1);
1139                 LogUtil.v("Package changed with UID " + uidChanged);
1140                 explicitBroadcast.putExtra(Intent.EXTRA_UID, uidChanged);
1141                 switch (intent.getAction()) {
1142                     case Intent.ACTION_PACKAGE_DATA_CLEARED:
1143                         explicitBroadcast.putExtra(ACTION_KEY, PACKAGE_DATA_CLEARED);
1144                         mContext.sendBroadcastAsUser(explicitBroadcast, user);
1145                         break;
1146                     case Intent.ACTION_PACKAGE_FULLY_REMOVED:
1147                         // TODO (b/233373604): Propagate broadcast to users not currently running
1148                         explicitBroadcast.putExtra(ACTION_KEY, PACKAGE_FULLY_REMOVED);
1149                         mContext.sendBroadcastAsUser(explicitBroadcast, user);
1150                         break;
1151                     case Intent.ACTION_PACKAGE_ADDED:
1152                         explicitBroadcast.putExtra(ACTION_KEY, PACKAGE_ADDED);
1153                         // For users where the app is merely being updated rather than added, we
1154                         // don't want to send the broadcast.
1155                         if (!intent.getExtras().getBoolean(Intent.EXTRA_REPLACING, false)) {
1156                             mContext.sendBroadcastAsUser(explicitBroadcast, user);
1157                         }
1158                         break;
1159                 }
1160             }
1161         }
1162     }
1163 
1164     // Check if caller has permission to invoke AdServicesManager APIs.
1165     @VisibleForTesting
enforceAdServicesManagerPermission()1166     void enforceAdServicesManagerPermission() {
1167         mContext.enforceCallingPermission(
1168                 AdServicesPermissions.ACCESS_ADSERVICES_MANAGER,
1169                 ERROR_MESSAGE_NOT_PERMITTED_TO_CALL_ADSERVICESMANAGER_API);
1170     }
1171 
1172     @Override
1173     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isAdIdEnabled()1174     public boolean isAdIdEnabled() {
1175         return executeGetter(/* defaultReturn= */ false,
1176                 (userId) -> mUserInstanceManager.getOrCreateUserConsentManagerInstance(
1177                         userId).isAdIdEnabled());
1178     }
1179 
1180     @Override
1181     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setAdIdEnabled(boolean isAdIdEnabled)1182     public void setAdIdEnabled(boolean isAdIdEnabled) {
1183         enforceAdServicesManagerPermission();
1184 
1185         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1186         LogUtil.v("setAdIdEnabled() for User Identifier %d", userIdentifier);
1187 
1188         try {
1189             mUserInstanceManager
1190                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1191                     .setAdIdEnabled(isAdIdEnabled);
1192         } catch (IOException e) {
1193             LogUtil.e(e, "Failed to call setAdIdEnabled().");
1194         }
1195     }
1196 
1197     @Override
1198     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isU18Account()1199     public boolean isU18Account() {
1200         return executeGetter(/* defaultReturn= */ false,
1201                 (userId) -> mUserInstanceManager.getOrCreateUserConsentManagerInstance(
1202                         userId).isU18Account());
1203     }
1204 
1205     @Override
1206     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setU18Account(boolean isU18Account)1207     public void setU18Account(boolean isU18Account) {
1208         enforceAdServicesManagerPermission();
1209 
1210         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1211         LogUtil.v("setU18Account() for User Identifier %d", userIdentifier);
1212 
1213         try {
1214             mUserInstanceManager
1215                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1216                     .setU18Account(isU18Account);
1217         } catch (IOException e) {
1218             LogUtil.e(e, "Failed to call setU18Account().");
1219         }
1220     }
1221 
1222     @Override
1223     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isEntryPointEnabled()1224     public boolean isEntryPointEnabled() {
1225         return executeGetter(/* defaultReturn= */ false,
1226                 (userId) -> mUserInstanceManager.getOrCreateUserConsentManagerInstance(
1227                         userId).isEntryPointEnabled());
1228     }
1229 
1230     @Override
1231     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setEntryPointEnabled(boolean isEntryPointEnabled)1232     public void setEntryPointEnabled(boolean isEntryPointEnabled) {
1233         enforceAdServicesManagerPermission();
1234 
1235         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1236         LogUtil.v("setEntryPointEnabled() for User Identifier %d", userIdentifier);
1237 
1238         try {
1239             mUserInstanceManager
1240                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1241                     .setEntryPointEnabled(isEntryPointEnabled);
1242         } catch (IOException e) {
1243             LogUtil.e(e, "Failed to call setEntryPointEnabled().");
1244         }
1245     }
1246 
1247     @Override
1248     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isAdultAccount()1249     public boolean isAdultAccount() {
1250         return executeGetter(/* defaultReturn= */ false,
1251                 (userId) -> mUserInstanceManager.getOrCreateUserConsentManagerInstance(
1252                         userId).isAdultAccount());
1253     }
1254 
1255     @Override
1256     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setAdultAccount(boolean isAdultAccount)1257     public void setAdultAccount(boolean isAdultAccount) {
1258         enforceAdServicesManagerPermission();
1259 
1260         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1261         LogUtil.v("setAdultAccount() for User Identifier %d", userIdentifier);
1262 
1263         try {
1264             mUserInstanceManager
1265                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1266                     .setAdultAccount(isAdultAccount);
1267         } catch (IOException e) {
1268             LogUtil.e(e, "Failed to call setAdultAccount().");
1269         }
1270     }
1271 
1272     @Override
1273     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
wasU18NotificationDisplayed()1274     public boolean wasU18NotificationDisplayed() {
1275         return executeGetter(/* defaultReturn= */ false,
1276                 (userId) -> mUserInstanceManager.getOrCreateUserConsentManagerInstance(
1277                         userId).wasU18NotificationDisplayed());
1278     }
1279 
1280     @Override
1281     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setU18NotificationDisplayed(boolean wasU18NotificationDisplayed)1282     public void setU18NotificationDisplayed(boolean wasU18NotificationDisplayed) {
1283         enforceAdServicesManagerPermission();
1284 
1285         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1286         LogUtil.v("setU18NotificationDisplayed() for User Identifier %d", userIdentifier);
1287 
1288         try {
1289             mUserInstanceManager
1290                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1291                     .setU18NotificationDisplayed(wasU18NotificationDisplayed);
1292         } catch (IOException e) {
1293             LogUtil.e(e, "Failed to call setU18NotificationDisplayed().");
1294         }
1295     }
1296 
1297     /** Get the current UX. */
1298     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getUx()1299     public String getUx() {
1300         enforceAdServicesManagerPermission();
1301 
1302         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1303         LogUtil.v("getUx() for User Identifier %d", userIdentifier);
1304         try {
1305             return mUserInstanceManager
1306                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1307                     .getUx();
1308         } catch (IOException e) {
1309             LogUtil.e(e, "Fail to get current UX: " + e.getMessage());
1310         }
1311         return PrivacySandboxUxCollection.UNSUPPORTED_UX.toString();
1312     }
1313 
1314     /** Set the currently running privacy sandbox feature on device. */
1315     @Override
1316     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setUx(String ux)1317     public void setUx(String ux) {
1318         enforceAdServicesManagerPermission();
1319 
1320         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1321         LogUtil.v("setUx() for User Identifier %d", userIdentifier);
1322         try {
1323             mUserInstanceManager.getOrCreateUserConsentManagerInstance(userIdentifier).setUx(ux);
1324         } catch (IOException e) {
1325             LogUtil.e(e, "Fail to set current UX: " + e.getMessage());
1326         }
1327     }
1328 
1329     /** Get the current enrollment channel. */
1330     @Override
1331     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
getEnrollmentChannel()1332     public String getEnrollmentChannel() {
1333         enforceAdServicesManagerPermission();
1334 
1335         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1336         LogUtil.v("getUx() for User Identifier %d", userIdentifier);
1337         try {
1338             return mUserInstanceManager
1339                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1340                     .getEnrollmentChannel();
1341         } catch (IOException e) {
1342             LogUtil.e(e, "Fail to get current enrollment channel: " + e.getMessage());
1343         }
1344         return PrivacySandboxUxCollection.UNSUPPORTED_UX.toString();
1345     }
1346 
1347     /** Set the current enrollment channel. */
1348     @Override
1349     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setEnrollmentChannel(String enrollmentChannel)1350     public void setEnrollmentChannel(String enrollmentChannel) {
1351         enforceAdServicesManagerPermission();
1352 
1353         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1354         LogUtil.v("setUx() for User Identifier %d", userIdentifier);
1355         try {
1356             mUserInstanceManager
1357                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1358                     .setEnrollmentChannel(enrollmentChannel);
1359         } catch (IOException e) {
1360             LogUtil.e(e, "Fail to set current enrollment channel: " + e.getMessage());
1361         }
1362     }
1363 
1364     @Override
1365     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isMeasurementDataReset()1366     public boolean isMeasurementDataReset() {
1367         return executeGetter(
1368                 /* defaultReturn= */ false,
1369                 (userId) ->
1370                         mUserInstanceManager
1371                                 .getOrCreateUserConsentManagerInstance(userId)
1372                                 .isMeasurementDataReset());
1373     }
1374 
1375     @Override
1376     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setMeasurementDataReset(boolean isMeasurementDataReset)1377     public void setMeasurementDataReset(boolean isMeasurementDataReset) {
1378         enforceAdServicesManagerPermission();
1379 
1380         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1381         LogUtil.v("isMeasurementDataReset() for User Identifier %d", userIdentifier);
1382 
1383         try {
1384             mUserInstanceManager
1385                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1386                     .setMeasurementDataReset(isMeasurementDataReset);
1387         } catch (IOException e) {
1388             LogUtil.e(e, "Failed to call isMeasurementDataReset().");
1389         }
1390     }
1391 
1392     @Override
1393     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
isPaDataReset()1394     public boolean isPaDataReset() {
1395         return executeGetter(
1396                 /* defaultReturn= */ false,
1397                 (userId) ->
1398                         mUserInstanceManager
1399                                 .getOrCreateUserConsentManagerInstance(userId)
1400                                 .isPaDataReset());
1401     }
1402 
1403     @Override
1404     @RequiresPermission(AdServicesPermissions.ACCESS_ADSERVICES_MANAGER)
setPaDataReset(boolean isPaDataReset)1405     public void setPaDataReset(boolean isPaDataReset) {
1406         enforceAdServicesManagerPermission();
1407 
1408         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1409         LogUtil.v("isPaDataReset() for User Identifier %d", userIdentifier);
1410 
1411         try {
1412             mUserInstanceManager
1413                     .getOrCreateUserConsentManagerInstance(userIdentifier)
1414                     .setPaDataReset(isPaDataReset);
1415         } catch (IOException e) {
1416             LogUtil.e(e, "Failed to call isPaDataReset().");
1417         }
1418     }
1419 
1420     @FunctionalInterface
1421     interface ThrowableGetter<R> {
apply(int userId)1422         R apply(int userId) throws IOException;
1423     }
1424 
executeGetter(R r, ThrowableGetter<R> function)1425     private <R> R executeGetter(R r, ThrowableGetter<R> function) {
1426         enforceAdServicesManagerPermission();
1427 
1428         final int userIdentifier = getUserIdentifierFromBinderCallingUid();
1429 
1430         String logPrefix = getClass().getSimpleName() + function.toString();
1431         LogUtil.v("%s called. User identifier: %s", logPrefix, userIdentifier);
1432 
1433         try {
1434             return function.apply(userIdentifier);
1435         } catch (IOException e) {
1436             LogUtil.e(e, logPrefix + " failed.");
1437             return r;
1438         }
1439     }
1440 }
1441