1 /* 2 * Copyright 2024 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.ondevicepersonalization; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertThrows; 21 import static org.junit.Assert.assertTrue; 22 23 import android.adservices.ondevicepersonalization.aidl.IExecuteCallback; 24 import android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationManagingService; 25 import android.adservices.ondevicepersonalization.aidl.IRegisterMeasurementEventCallback; 26 import android.adservices.ondevicepersonalization.aidl.IRequestSurfacePackageCallback; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.net.Uri; 30 import android.os.Bundle; 31 import android.os.IBinder; 32 import android.os.RemoteException; 33 import android.os.SystemClock; 34 import android.util.Log; 35 36 import androidx.test.core.app.ApplicationProvider; 37 import androidx.test.ext.junit.runners.AndroidJUnit4; 38 39 import com.android.federatedcompute.internal.util.AbstractServiceBinder; 40 import com.android.ondevicepersonalization.testing.utils.ResultReceiver; 41 42 import org.junit.Test; 43 import org.junit.runner.RunWith; 44 45 import java.util.concurrent.Executor; 46 import java.util.concurrent.Executors; 47 48 @RunWith(AndroidJUnit4.class) 49 public final class OnDevicePersonalizationSystemEventManagerTest { 50 private static final String TAG = "OnDevicePersonalizationManagerTest"; 51 private static final String KEY_OP = "op"; 52 private Context mContext = ApplicationProvider.getApplicationContext(); 53 private TestServiceBinder mTestBinder = new TestServiceBinder( 54 IOnDevicePersonalizationManagingService.Stub.asInterface(new TestService())); 55 private OnDevicePersonalizationSystemEventManager mManager = 56 new OnDevicePersonalizationSystemEventManager(mContext, mTestBinder); 57 58 @Test testnotifyMeasurementEventSuccess()59 public void testnotifyMeasurementEventSuccess() throws Exception { 60 var receiver = new ResultReceiver<Void>(); 61 mManager.notifyMeasurementEvent( 62 new MeasurementWebTriggerEventParams.Builder( 63 Uri.parse("http://ok"), 64 "com.example.browser", 65 ComponentName.createRelative("com.example", ".Example")) 66 .build(), 67 Executors.newSingleThreadExecutor(), 68 receiver); 69 assertTrue(receiver.isSuccess()); 70 assertFalse(receiver.isError()); 71 } 72 73 @Test testnotifyMeasurementEventError()74 public void testnotifyMeasurementEventError() throws Exception { 75 var receiver = new ResultReceiver<Void>(); 76 mManager.notifyMeasurementEvent( 77 new MeasurementWebTriggerEventParams.Builder( 78 Uri.parse("http://error"), 79 "com.example.browser", 80 ComponentName.createRelative("com.example", ".Example")) 81 .build(), 82 Executors.newSingleThreadExecutor(), 83 receiver); 84 assertFalse(receiver.isSuccess()); 85 assertTrue(receiver.isError()); 86 } 87 88 @Test testnotifyMeasurementEventPropagatesIae()89 public void testnotifyMeasurementEventPropagatesIae() throws Exception { 90 assertThrows( 91 IllegalArgumentException.class, 92 () -> mManager.notifyMeasurementEvent( 93 new MeasurementWebTriggerEventParams.Builder( 94 Uri.parse("http://iae"), 95 "com.example.browser", 96 ComponentName.createRelative("com.example", ".Example")) 97 .build(), 98 Executors.newSingleThreadExecutor(), 99 new ResultReceiver<Void>())); 100 } 101 102 @Test testnotifyMeasurementEventPropagatesNpe()103 public void testnotifyMeasurementEventPropagatesNpe() throws Exception { 104 assertThrows( 105 NullPointerException.class, 106 () -> mManager.notifyMeasurementEvent( 107 new MeasurementWebTriggerEventParams.Builder( 108 Uri.parse("http://npe"), 109 "com.example.browser", 110 ComponentName.createRelative("com.example", ".Example")) 111 .build(), 112 Executors.newSingleThreadExecutor(), 113 new ResultReceiver<Void>())); 114 } 115 116 @Test testnotifyMeasurementEventCatchesExceptions()117 public void testnotifyMeasurementEventCatchesExceptions() throws Exception { 118 var receiver = new ResultReceiver<Void>(); 119 mManager.notifyMeasurementEvent( 120 new MeasurementWebTriggerEventParams.Builder( 121 Uri.parse("http://ise"), 122 "com.example.browser", 123 ComponentName.createRelative("com.example", ".Example")) 124 .build(), 125 Executors.newSingleThreadExecutor(), 126 receiver); 127 assertFalse(receiver.isSuccess()); 128 assertTrue(receiver.isError()); 129 assertTrue(receiver.getException() instanceof IllegalStateException); 130 } 131 132 class TestService extends IOnDevicePersonalizationManagingService.Stub { 133 @Override getVersion()134 public String getVersion() { 135 return "1.0"; 136 } 137 138 @Override execute( String callingPackageName, ComponentName handler, Bundle params, CallerMetadata metadata, IExecuteCallback callback)139 public void execute( 140 String callingPackageName, 141 ComponentName handler, 142 Bundle params, 143 CallerMetadata metadata, 144 IExecuteCallback callback) { 145 throw new UnsupportedOperationException(); 146 } 147 148 @Override requestSurfacePackage( String surfacePackageToken, IBinder hostToken, int displayId, int width, int height, CallerMetadata metadata, IRequestSurfacePackageCallback callback)149 public void requestSurfacePackage( 150 String surfacePackageToken, 151 IBinder hostToken, 152 int displayId, 153 int width, 154 int height, 155 CallerMetadata metadata, 156 IRequestSurfacePackageCallback callback) { 157 throw new UnsupportedOperationException(); 158 } 159 160 @Override registerMeasurementEvent( int eventType, Bundle params, CallerMetadata metadata, IRegisterMeasurementEventCallback callback)161 public void registerMeasurementEvent( 162 int eventType, 163 Bundle params, 164 CallerMetadata metadata, 165 IRegisterMeasurementEventCallback callback) { 166 try { 167 MeasurementWebTriggerEventParamsParcel wtparams = params.getParcelable( 168 Constants.EXTRA_MEASUREMENT_WEB_TRIGGER_PARAMS, 169 MeasurementWebTriggerEventParamsParcel.class); 170 String url = wtparams.getDestinationUrl().toString(); 171 if (url.equals("http://error")) { 172 callback.onError(Constants.STATUS_INTERNAL_ERROR, 173 new CalleeMetadata.Builder().setCallbackInvokeTimeMillis( 174 SystemClock.elapsedRealtime()).build()); 175 } else if (url.equals("http://iae")) { 176 throw new IllegalArgumentException(); 177 } else if (url.equals("http://npe")) { 178 throw new NullPointerException(); 179 } else if (url.equals("http://ise")) { 180 throw new IllegalStateException(); 181 } else { 182 callback.onSuccess( 183 new CalleeMetadata.Builder().setCallbackInvokeTimeMillis( 184 SystemClock.elapsedRealtime()).build()); 185 } 186 } catch (RemoteException e) { 187 Log.e(TAG, "callback error", e); 188 } 189 } 190 191 @Override logApiCallStats( String sdkPackageName, int apiName, long latencyMillis, long rpcCallLatencyMillis, long rpcReturnLatencyMillis, int responseCode)192 public void logApiCallStats( 193 String sdkPackageName, 194 int apiName, 195 long latencyMillis, 196 long rpcCallLatencyMillis, 197 long rpcReturnLatencyMillis, 198 int responseCode) { 199 } 200 } 201 202 class TestServiceBinder 203 extends AbstractServiceBinder<IOnDevicePersonalizationManagingService> { 204 private final IOnDevicePersonalizationManagingService mService; TestServiceBinder(IOnDevicePersonalizationManagingService service)205 TestServiceBinder(IOnDevicePersonalizationManagingService service) { 206 mService = service; 207 } 208 209 @Override getService(Executor executor)210 public IOnDevicePersonalizationManagingService getService(Executor executor) { 211 return mService; 212 } 213 214 @Override unbindFromService()215 public void unbindFromService() {} 216 } 217 } 218