/* * Copyright 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.adservices.ondevicepersonalization; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.adservices.ondevicepersonalization.aidl.IExecuteCallback; import android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationManagingService; import android.adservices.ondevicepersonalization.aidl.IRegisterMeasurementEventCallback; import android.adservices.ondevicepersonalization.aidl.IRequestSurfacePackageCallback; import android.content.ComponentName; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.util.Log; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.android.federatedcompute.internal.util.AbstractServiceBinder; import com.android.ondevicepersonalization.testing.utils.ResultReceiver; import org.junit.Test; import org.junit.runner.RunWith; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @RunWith(AndroidJUnit4.class) public final class OnDevicePersonalizationSystemEventManagerTest { private static final String TAG = "OnDevicePersonalizationManagerTest"; private static final String KEY_OP = "op"; private Context mContext = ApplicationProvider.getApplicationContext(); private TestServiceBinder mTestBinder = new TestServiceBinder( IOnDevicePersonalizationManagingService.Stub.asInterface(new TestService())); private OnDevicePersonalizationSystemEventManager mManager = new OnDevicePersonalizationSystemEventManager(mContext, mTestBinder); @Test public void testnotifyMeasurementEventSuccess() throws Exception { var receiver = new ResultReceiver(); mManager.notifyMeasurementEvent( new MeasurementWebTriggerEventParams.Builder( Uri.parse("http://ok"), "com.example.browser", ComponentName.createRelative("com.example", ".Example")) .build(), Executors.newSingleThreadExecutor(), receiver); assertTrue(receiver.isSuccess()); assertFalse(receiver.isError()); } @Test public void testnotifyMeasurementEventError() throws Exception { var receiver = new ResultReceiver(); mManager.notifyMeasurementEvent( new MeasurementWebTriggerEventParams.Builder( Uri.parse("http://error"), "com.example.browser", ComponentName.createRelative("com.example", ".Example")) .build(), Executors.newSingleThreadExecutor(), receiver); assertFalse(receiver.isSuccess()); assertTrue(receiver.isError()); } @Test public void testnotifyMeasurementEventPropagatesIae() throws Exception { assertThrows( IllegalArgumentException.class, () -> mManager.notifyMeasurementEvent( new MeasurementWebTriggerEventParams.Builder( Uri.parse("http://iae"), "com.example.browser", ComponentName.createRelative("com.example", ".Example")) .build(), Executors.newSingleThreadExecutor(), new ResultReceiver())); } @Test public void testnotifyMeasurementEventPropagatesNpe() throws Exception { assertThrows( NullPointerException.class, () -> mManager.notifyMeasurementEvent( new MeasurementWebTriggerEventParams.Builder( Uri.parse("http://npe"), "com.example.browser", ComponentName.createRelative("com.example", ".Example")) .build(), Executors.newSingleThreadExecutor(), new ResultReceiver())); } @Test public void testnotifyMeasurementEventCatchesExceptions() throws Exception { var receiver = new ResultReceiver(); mManager.notifyMeasurementEvent( new MeasurementWebTriggerEventParams.Builder( Uri.parse("http://ise"), "com.example.browser", ComponentName.createRelative("com.example", ".Example")) .build(), Executors.newSingleThreadExecutor(), receiver); assertFalse(receiver.isSuccess()); assertTrue(receiver.isError()); assertTrue(receiver.getException() instanceof IllegalStateException); } class TestService extends IOnDevicePersonalizationManagingService.Stub { @Override public String getVersion() { return "1.0"; } @Override public void execute( String callingPackageName, ComponentName handler, Bundle params, CallerMetadata metadata, IExecuteCallback callback) { throw new UnsupportedOperationException(); } @Override public void requestSurfacePackage( String surfacePackageToken, IBinder hostToken, int displayId, int width, int height, CallerMetadata metadata, IRequestSurfacePackageCallback callback) { throw new UnsupportedOperationException(); } @Override public void registerMeasurementEvent( int eventType, Bundle params, CallerMetadata metadata, IRegisterMeasurementEventCallback callback) { try { MeasurementWebTriggerEventParamsParcel wtparams = params.getParcelable( Constants.EXTRA_MEASUREMENT_WEB_TRIGGER_PARAMS, MeasurementWebTriggerEventParamsParcel.class); String url = wtparams.getDestinationUrl().toString(); if (url.equals("http://error")) { callback.onError(Constants.STATUS_INTERNAL_ERROR, new CalleeMetadata.Builder().setCallbackInvokeTimeMillis( SystemClock.elapsedRealtime()).build()); } else if (url.equals("http://iae")) { throw new IllegalArgumentException(); } else if (url.equals("http://npe")) { throw new NullPointerException(); } else if (url.equals("http://ise")) { throw new IllegalStateException(); } else { callback.onSuccess( new CalleeMetadata.Builder().setCallbackInvokeTimeMillis( SystemClock.elapsedRealtime()).build()); } } catch (RemoteException e) { Log.e(TAG, "callback error", e); } } @Override public void logApiCallStats( String sdkPackageName, int apiName, long latencyMillis, long rpcCallLatencyMillis, long rpcReturnLatencyMillis, int responseCode) { } } class TestServiceBinder extends AbstractServiceBinder { private final IOnDevicePersonalizationManagingService mService; TestServiceBinder(IOnDevicePersonalizationManagingService service) { mService = service; } @Override public IOnDevicePersonalizationManagingService getService(Executor executor) { return mService; } @Override public void unbindFromService() {} } }