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 android.adservices.adid;
17 
18 import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_AD_ID;
19 
20 import android.adservices.common.AdServicesOutcomeReceiver;
21 import android.adservices.common.OutcomeReceiverConverter;
22 import android.annotation.CallbackExecutor;
23 import android.annotation.FlaggedApi;
24 import android.annotation.NonNull;
25 import android.annotation.RequiresPermission;
26 import android.app.sdksandbox.SandboxedSdkContext;
27 import android.content.Context;
28 import android.os.Build;
29 import android.os.OutcomeReceiver;
30 
31 import androidx.annotation.RequiresApi;
32 
33 import com.android.adservices.flags.Flags;
34 
35 import java.util.concurrent.Executor;
36 
37 /**
38  * AdId Manager provides APIs for app and ad-SDKs to access advertising ID. The advertising ID is a
39  * unique, per-device, user-resettable ID for advertising. It gives users better controls and
40  * provides developers with a simple, standard system to continue to monetize their apps via
41  * personalized ads (formerly known as interest-based ads).
42  */
43 public class AdIdManager {
44     /**
45      * Service used for registering AdIdManager in the system service registry.
46      *
47      * @hide
48      */
49     public static final String ADID_SERVICE = "adid_service";
50 
51     // When an app calls the AdId API directly, it sets the SDK name to empty string.
52     static final String EMPTY_SDK = "";
53 
54     private final AdIdCompatibleManager mImpl;
55 
56     /**
57      * Factory method for creating an instance of AdIdManager.
58      *
59      * @param context The {@link Context} to use
60      * @return A {@link AdIdManager} instance
61      */
62     @NonNull
get(@onNull Context context)63     public static AdIdManager get(@NonNull Context context) {
64         // On T+, context.getSystemService() does more than just call constructor.
65         return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
66                 ? context.getSystemService(AdIdManager.class)
67                 : new AdIdManager(context);
68     }
69 
70     /**
71      * Create AdIdManager
72      *
73      * @hide
74      */
AdIdManager(Context context)75     public AdIdManager(Context context) {
76         // In case the AdIdManager is initiated from inside a sdk_sandbox process the fields
77         // will be immediately rewritten by the initialize method below.
78         mImpl = new AdIdCompatibleManager(context);
79     }
80 
81     /**
82      * Initializes {@link AdIdManager} with the given {@code context}.
83      *
84      * <p>This method is called by the {@link SandboxedSdkContext} to propagate the correct context.
85      * For more information check the javadoc on the {@link
86      * android.app.sdksandbox.SdkSandboxSystemServiceRegistry}.
87      *
88      * @hide
89      * @see android.app.sdksandbox.SdkSandboxSystemServiceRegistry
90      */
initialize(Context context)91     public AdIdManager initialize(Context context) {
92         mImpl.initialize(context);
93         return this;
94     }
95 
96     /**
97      * Return the AdId.
98      *
99      * @param executor The executor to run callback.
100      * @param callback The callback that's called after adid are available or an error occurs.
101      */
102     @RequiresApi(Build.VERSION_CODES.S)
103     @RequiresPermission(ACCESS_ADSERVICES_AD_ID)
104     @NonNull
getAdId( @onNull @allbackExecutor Executor executor, @NonNull OutcomeReceiver<AdId, Exception> callback)105     public void getAdId(
106             @NonNull @CallbackExecutor Executor executor,
107             @NonNull OutcomeReceiver<AdId, Exception> callback) {
108         mImpl.getAdId(executor, OutcomeReceiverConverter.toAdServicesOutcomeReceiver(callback));
109     }
110 
111     /**
112      * Return the AdId. For use on Android R or lower.
113      *
114      * @param executor The executor to run callback.
115      * @param callback The callback that's called after adid are available or an error occurs.
116      */
117     @FlaggedApi(Flags.FLAG_ADSERVICES_OUTCOMERECEIVER_R_API_ENABLED)
118     @RequiresPermission(ACCESS_ADSERVICES_AD_ID)
119     @NonNull
getAdId( @onNull @allbackExecutor Executor executor, @NonNull AdServicesOutcomeReceiver<AdId, Exception> callback)120     public void getAdId(
121             @NonNull @CallbackExecutor Executor executor,
122             @NonNull AdServicesOutcomeReceiver<AdId, Exception> callback) {
123         mImpl.getAdId(executor, callback);
124     }
125 
126     /**
127      * If the service is in an APK (as opposed to the system service), unbind it from the service to
128      * allow the APK process to die.
129      *
130      * @hide
131      */
132     // TODO: change to @VisibleForTesting
unbindFromService()133     public void unbindFromService() {
134         mImpl.unbindFromService();
135     }
136 }
137