1 /* 2 * Copyright (C) 2023 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.test.scenario.adservices.topics; 18 19 import static com.android.adservices.service.DebugFlagsConstants.KEY_CONSENT_MANAGER_DEBUG_MODE; 20 import static com.android.adservices.service.FlagsConstants.KEY_DISABLE_TOPICS_ENROLLMENT_CHECK; 21 22 import android.adservices.clients.topics.AdvertisingTopicsClient; 23 import android.adservices.topics.GetTopicsResponse; 24 import android.content.Context; 25 import android.platform.test.option.StringOption; 26 import android.platform.test.scenario.annotation.Scenario; 27 import android.util.Log; 28 29 import androidx.test.core.app.ApplicationProvider; 30 31 import com.android.adservices.common.AdServicesFlagsSetterRule; 32 33 import org.junit.Rule; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 import org.junit.runners.JUnit4; 37 38 import java.util.concurrent.Executor; 39 import java.util.concurrent.Executors; 40 41 /** Crystalball test for Topics API to collect System Heath metrics. */ 42 @Scenario 43 @RunWith(JUnit4.class) 44 public class GetTopicsApiCall { 45 private static final String TAG = "GetTopicsApiCall"; 46 47 protected static final Context sContext = ApplicationProvider.getApplicationContext(); 48 private static final Executor CALLBACK_EXECUTOR = Executors.newCachedThreadPool(); 49 private static final String DEFAULT_SDKNAME = "sdk1"; 50 51 private static final String OPTION_SDKNAME = "sdk_name"; 52 53 // To supply value, use {@code -e sdk_name sdk1} in the instrumentation command. 54 @Rule(order = 0) 55 public StringOption sdkOption = 56 new StringOption(OPTION_SDKNAME).setRequired(false).setDefault(DEFAULT_SDKNAME); 57 58 @Rule(order = 1) 59 public final AdServicesFlagsSetterRule flags = 60 AdServicesFlagsSetterRule.forGlobalKillSwitchDisabledTests() 61 .setTopicsKillSwitch(false) 62 .setDebugFlag(KEY_CONSENT_MANAGER_DEBUG_MODE, true) 63 .setFlag(KEY_DISABLE_TOPICS_ENROLLMENT_CHECK, true) 64 .setCompatModeFlags(); 65 measureGetTopics(String label)66 private void measureGetTopics(String label) throws Exception { 67 Log.i(TAG, "Calling getTopics()"); 68 final long start = System.currentTimeMillis(); 69 AdvertisingTopicsClient advertisingTopicsClient = 70 new android.adservices.clients.topics.AdvertisingTopicsClient.Builder() 71 .setContext(sContext) 72 .setSdkName(sdkOption.get()) 73 .setExecutor(CALLBACK_EXECUTOR) 74 .build(); 75 76 GetTopicsResponse unUsedTopicsResponse = advertisingTopicsClient.getTopics().get(); 77 78 final long duration = System.currentTimeMillis() - start; 79 // TODO(b/234452723): In the future, we will want to use either statsd or perfetto instead 80 // Two major benefits are that statsd or perfetto will allow you to collect field data and 81 // the metrics are going to be less reliable if you collect them from logcat because they 82 // are impacted by latency in writing the messages to logcat and making the API calls. 83 Log.i(TAG, "(" + label + ": " + duration + ")"); 84 } 85 86 @Test testTopicsManager()87 public void testTopicsManager() throws Exception { 88 measureGetTopics("TOPICS_COLD_START_LATENCY_METRIC"); 89 // We need to sleep here to prevent going above the Rate Limit. 90 Thread.sleep(1000); 91 measureGetTopics("TOPICS_HOT_START_LATENCY_METRIC"); 92 } 93 } 94