1 /* 2 * Copyright 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.ondevicepersonalization; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertThrows; 21 22 import android.adservices.ondevicepersonalization.aidl.IDataAccessService; 23 import android.adservices.ondevicepersonalization.aidl.IDataAccessServiceCallback; 24 import android.net.Uri; 25 import android.os.Bundle; 26 import android.os.PersistableBundle; 27 import android.os.RemoteException; 28 29 import androidx.test.ext.junit.runners.AndroidJUnit4; 30 import androidx.test.filters.SmallTest; 31 32 import org.junit.Test; 33 import org.junit.runner.RunWith; 34 35 import java.nio.charset.StandardCharsets; 36 37 @SmallTest 38 @RunWith(AndroidJUnit4.class) 39 public class EventUrlProviderTest { 40 static final int EVENT_TYPE_ERROR = 10; 41 private final EventUrlProvider mEventUrlProvider = 42 new EventUrlProvider(new TestDataService()); 43 private static final byte[] RESPONSE_BYTES = {'A', 'B'}; 44 testGetEventUrlWithEmptyResponse()45 @Test public void testGetEventUrlWithEmptyResponse() throws Exception { 46 PersistableBundle params = new PersistableBundle(); 47 params.putInt("type", 5); 48 params.putString("id", "abc"); 49 assertEquals( 50 "odp://5-abc-null-null-null", 51 mEventUrlProvider.createEventTrackingUrlWithResponse( 52 params, null, null).toString()); 53 } 54 testGetEventUrlReturnsResponseFromService()55 @Test public void testGetEventUrlReturnsResponseFromService() throws Exception { 56 PersistableBundle params = new PersistableBundle(); 57 params.putInt("type", 5); 58 params.putString("id", "abc"); 59 assertEquals( 60 "odp://5-abc-AB-image/gif-null", 61 mEventUrlProvider.createEventTrackingUrlWithResponse( 62 params, RESPONSE_BYTES, "image/gif").toString()); 63 } 64 testGetEventUrlWithRedirectReturnsResponseFromService()65 @Test public void testGetEventUrlWithRedirectReturnsResponseFromService() throws Exception { 66 PersistableBundle params = new PersistableBundle(); 67 params.putInt("type", 5); 68 params.putString("id", "abc"); 69 assertEquals( 70 "odp://5-abc-null-null-http://def", 71 mEventUrlProvider.createEventTrackingUrlWithRedirect( 72 params, Uri.parse("http://def")) 73 .toString()); 74 } 75 testGetEventUrlThrowsOnError()76 @Test public void testGetEventUrlThrowsOnError() throws Exception { 77 // EventType 10 triggers error in the mock service. 78 PersistableBundle params = new PersistableBundle(); 79 params.putInt("type", EVENT_TYPE_ERROR); 80 params.putString("id", "abc"); 81 assertThrows( 82 IllegalStateException.class, 83 () -> mEventUrlProvider.createEventTrackingUrlWithResponse( 84 params, null, null)); 85 } 86 87 class TestDataService extends IDataAccessService.Stub { 88 @Override onRequest( int operation, Bundle params, IDataAccessServiceCallback callback)89 public void onRequest( 90 int operation, 91 Bundle params, 92 IDataAccessServiceCallback callback) { 93 if (operation == Constants.DATA_ACCESS_OP_GET_EVENT_URL) { 94 PersistableBundle eventParams = params.getParcelable( 95 Constants.EXTRA_EVENT_PARAMS, PersistableBundle.class); 96 int eventType = eventParams.getInt("type"); 97 String id = eventParams.getString("id"); 98 byte[] responseDataBytes = params.getByteArray(Constants.EXTRA_RESPONSE_DATA); 99 String responseData = (responseDataBytes != null) 100 ? new String(responseDataBytes, StandardCharsets.UTF_8) : "null"; 101 String mimeType = params.getString(Constants.EXTRA_MIME_TYPE); 102 String destinationUrl = params.getString(Constants.EXTRA_DESTINATION_URL); 103 if (eventType == EVENT_TYPE_ERROR) { 104 try { 105 callback.onError(Constants.STATUS_INTERNAL_ERROR); 106 } catch (RemoteException e) { 107 // Ignored. 108 } 109 } else { 110 String url = String.format( 111 "odp://%d-%s-%s-%s-%s", eventType, id, responseData, mimeType, 112 destinationUrl); 113 Bundle result = new Bundle(); 114 result.putParcelable(Constants.EXTRA_RESULT, Uri.parse(url)); 115 try { 116 callback.onSuccess(result); 117 } catch (RemoteException e) { 118 // Ignored. 119 } 120 } 121 } else { 122 throw new IllegalStateException("Unexpected test input"); 123 } 124 } 125 @Override logApiCallStats(int apiName, long latencyMillis, int responseCode)126 public void logApiCallStats(int apiName, long latencyMillis, int responseCode) {} 127 } 128 } 129