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 android.adservices.common; 18 19 import static android.adservices.common.AdServicesPermissions.ACCESS_ADSERVICES_STATE; 20 import static android.adservices.common.AdServicesPermissions.MODIFY_ADSERVICES_STATE; 21 22 import android.annotation.CallbackExecutor; 23 import android.annotation.NonNull; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SystemApi; 26 import android.content.Context; 27 import android.os.Build; 28 import android.os.OutcomeReceiver; 29 import android.os.RemoteException; 30 31 import androidx.annotation.RequiresApi; 32 33 import com.android.adservices.AdServicesCommon; 34 import com.android.adservices.LogUtil; 35 import com.android.adservices.ServiceBinder; 36 37 import java.util.concurrent.Executor; 38 39 /** 40 * AdServicesCommonManager contains APIs common across the various AdServices. It provides two 41 * SystemApis: 42 * 43 * <ul> 44 * <li>isAdServicesEnabled - allows to get AdServices state. 45 * <li>setAdServicesEntryPointEnabled - allows to control AdServices state. 46 * </ul> 47 * 48 * <p>The instance of the {@link AdServicesCommonManager} can be obtained using {@link 49 * Context#getSystemService} and {@link AdServicesCommonManager} class. 50 * 51 * @hide 52 */ 53 // TODO(b/269798827): Enable for R. 54 @RequiresApi(Build.VERSION_CODES.S) 55 @SystemApi 56 public class AdServicesCommonManager { 57 /** @hide */ 58 public static final String AD_SERVICES_COMMON_SERVICE = "ad_services_common_service"; 59 60 private final Context mContext; 61 private final ServiceBinder<IAdServicesCommonService> 62 mAdServicesCommonServiceBinder; 63 64 /** 65 * Factory method for creating an instance of AdServicesCommonManager. 66 * 67 * @param context The {@link Context} to use 68 * @return A {@link AdServicesCommonManager} instance 69 */ 70 @NonNull get(@onNull Context context)71 public static AdServicesCommonManager get(@NonNull Context context) { 72 // On T+, context.getSystemService() does more than just call constructor. 73 return (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) 74 ? context.getSystemService(AdServicesCommonManager.class) 75 : new AdServicesCommonManager(context); 76 } 77 78 /** 79 * Create AdServicesCommonManager. 80 * 81 * @hide 82 */ AdServicesCommonManager(@onNull Context context)83 public AdServicesCommonManager(@NonNull Context context) { 84 mContext = context; 85 mAdServicesCommonServiceBinder = ServiceBinder.getServiceBinder( 86 context, 87 AdServicesCommon.ACTION_AD_SERVICES_COMMON_SERVICE, 88 IAdServicesCommonService.Stub::asInterface); 89 } 90 91 @NonNull getService()92 private IAdServicesCommonService getService() { 93 IAdServicesCommonService service = 94 mAdServicesCommonServiceBinder.getService(); 95 if (service == null) { 96 throw new IllegalStateException("Unable to find the service"); 97 } 98 return service; 99 } 100 101 /** 102 * Get the AdService's enablement state which represents whether AdServices feature is enabled 103 * or not. 104 * 105 * @hide 106 */ 107 @SystemApi 108 @RequiresPermission(ACCESS_ADSERVICES_STATE) isAdServicesEnabled( @onNull @allbackExecutor Executor executor, @NonNull OutcomeReceiver<Boolean, Exception> callback)109 public void isAdServicesEnabled( 110 @NonNull @CallbackExecutor Executor executor, 111 @NonNull OutcomeReceiver<Boolean, Exception> callback) { 112 final IAdServicesCommonService service = getService(); 113 try { 114 service.isAdServicesEnabled( 115 new IAdServicesCommonCallback.Stub() { 116 @Override 117 public void onResult(IsAdServicesEnabledResult result) { 118 executor.execute( 119 () -> { 120 callback.onResult(result.getAdServicesEnabled()); 121 }); 122 } 123 124 @Override 125 public void onFailure(int statusCode) { 126 executor.execute( 127 () -> 128 callback.onError( 129 AdServicesStatusUtils.asException(statusCode))); 130 } 131 }); 132 } catch (RemoteException e) { 133 LogUtil.e(e, "RemoteException"); 134 executor.execute( 135 () -> callback.onError(new IllegalStateException("Internal Error!", e))); 136 } 137 } 138 139 /** 140 * Sets the AdService's enablement state based on the provided parameters. 141 * 142 * <p>As a result of the AdServices state, {@code adServicesEntryPointEnabled}, {@code 143 * adIdEnabled}, appropriate notification may be displayed to the user. It's displayed only once 144 * when all the following conditions are met: 145 * 146 * <ul> 147 * <li>AdServices state - enabled. 148 * <li>adServicesEntryPointEnabled - true. 149 * </ul> 150 * 151 * @param adServicesEntryPointEnabled indicate entry point enabled or not 152 * @param adIdEnabled indicate user opt-out of adid or not 153 * @hide 154 */ 155 @SystemApi 156 @RequiresPermission(MODIFY_ADSERVICES_STATE) setAdServicesEnabled(boolean adServicesEntryPointEnabled, boolean adIdEnabled)157 public void setAdServicesEnabled(boolean adServicesEntryPointEnabled, boolean adIdEnabled) { 158 final IAdServicesCommonService service = getService(); 159 try { 160 service.setAdServicesEnabled(adServicesEntryPointEnabled, adIdEnabled); 161 } catch (RemoteException e) { 162 LogUtil.e(e, "RemoteException"); 163 } 164 } 165 } 166