CTS tests for the smartspace service
Test: atest CtsSmartspaceServiceTestCases
Bug: 176851064
Change-Id: I20e740e74eeb969dadcb22c0c83aa0b9942bab97
diff --git a/tests/smartspace/Android.bp b/tests/smartspace/Android.bp
new file mode 100644
index 0000000..33b33c5
--- /dev/null
+++ b/tests/smartspace/Android.bp
@@ -0,0 +1,31 @@
+// Copyright (C) 2019 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.
+
+android_test {
+ name: "CtsSmartspaceServiceTestCases",
+ defaults: ["cts_defaults"],
+ static_libs: [
+ "androidx.annotation_annotation",
+ "compatibility-device-util-axt",
+ "ctstestrunner-axt",
+ "truth-prebuilt",
+ ],
+ srcs: ["src/**/*.java"],
+ // Tag this module as a cts test artifact
+ test_suites: [
+ "cts",
+ "general-tests",
+ ],
+ sdk_version: "test_current",
+}
diff --git a/tests/smartspace/AndroidManifest.xml b/tests/smartspace/AndroidManifest.xml
new file mode 100644
index 0000000..4a0658d
--- /dev/null
+++ b/tests/smartspace/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2019 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.smartspace.cts"
+ android:targetSandboxVersion="2">
+
+ <uses-permission android:name="android.permission.MANAGE_SMARTSPACE"/>
+
+ <application>
+ <service android:name=".CtsSmartspaceService"
+ android:exported="true"
+ android:label="CtsDummySmartspaceService">
+ <intent-filter>
+ <!-- This constant must match SmartspaceService.SERVICE_INTERFACE -->
+ <action android:name="android.service.smartspace.SmartspaceService"/>
+ </intent-filter>
+ </service>
+
+ <!-- TODO(b/111701043): Update with required permissions -->
+ <uses-library android:name="android.test.runner"/>
+
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="CTS tests for the App Prediction Framework APIs."
+ android:targetPackage="android.smartspace.cts">
+ </instrumentation>
+
+</manifest>
diff --git a/tests/smartspace/AndroidTest.xml b/tests/smartspace/AndroidTest.xml
new file mode 100644
index 0000000..ad3aeeb
--- /dev/null
+++ b/tests/smartspace/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Config for Smartspace CTS tests.">
+ <option name="test-suite-tag" value="cts"/>
+ <option name="config-descriptor:metadata" key="component" value="framework"/>
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app"/>
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi"/>
+ <option name="config-descriptor:metadata" key="parameter" value="secondary_user"/>
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true"/>
+ <option name="test-file-name" value="CtsSmartspaceServiceTestCases.apk"/>
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="android.smartspace.cts"/>
+ <!-- 20x default timeout of 600sec -->
+ <option name="shell-timeout" value="12000000"/>
+ </test>
+
+</configuration>
diff --git a/tests/smartspace/OWNERS b/tests/smartspace/OWNERS
new file mode 100644
index 0000000..4a61d75
--- /dev/null
+++ b/tests/smartspace/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 487497
+srazdan@google.com
+alexmang@google.com
diff --git a/tests/smartspace/TEST_MAPPING b/tests/smartspace/TEST_MAPPING
new file mode 100644
index 0000000..58b65d1
--- /dev/null
+++ b/tests/smartspace/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsSmartspaceServiceTestCases"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/tests/smartspace/src/android/smartspace/cts/CtsSmartspaceService.java b/tests/smartspace/src/android/smartspace/cts/CtsSmartspaceService.java
new file mode 100644
index 0000000..a285511
--- /dev/null
+++ b/tests/smartspace/src/android/smartspace/cts/CtsSmartspaceService.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2021 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.smartspace.cts;
+
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceSessionId;
+import android.app.smartspace.SmartspaceTarget;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.os.Process;
+import android.service.smartspace.SmartspaceService;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+public class CtsSmartspaceService extends SmartspaceService {
+
+ private static final boolean DEBUG = true;
+ public static final String EXTRA_REPORTER = "extra_reporter";
+ public static final String MY_PACKAGE = "android.smartspace.cts";
+ public static final String SERVICE_NAME = MY_PACKAGE + "/."
+ + CtsSmartspaceService.class.getSimpleName();
+ private static final String TAG = CtsSmartspaceService.class.getSimpleName();
+
+ private static Watcher sWatcher;
+
+ private final ArrayMap<SmartspaceSessionId, List<SmartspaceTarget>> targets = new ArrayMap<>();
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+// Log.d(TAG, "onCreate mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) Log.d(TAG, "onCreate");
+ }
+
+ @Override
+ public void onCreateSmartspaceSession(SmartspaceConfig config, SmartspaceSessionId sessionId) {
+// Log.d(TAG, "onCreateSmartspaceSession mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) Log.d(TAG, "onCreateSmartspaceSession");
+
+ if (sWatcher.verifier != null) {
+ Log.e(TAG, "onCreateSmartspaceSession, trying to set verifier when it already exists");
+ }
+ targets.put(sessionId, new ArrayList<>());
+ sWatcher.verifier = Mockito.mock(CtsSmartspaceService.class);
+ sWatcher.created.countDown();
+ }
+
+ @Override
+ public void notifySmartspaceEvent(SmartspaceSessionId sessionId, SmartspaceTargetEvent event) {
+// Log.d(TAG, "notifySmartspaceEvent mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG){
+ Log.d(TAG, "notifySmartspaceEvent sessionId=" + sessionId + ", event=" + event.toString());
+ }
+ if(event.getSmartspaceTarget() != null) {
+ targets.get(sessionId).add(event.getSmartspaceTarget());
+ }
+ sWatcher.verifier.notifySmartspaceEvent(sessionId, event);
+ }
+
+ @Override
+ public void onRequestSmartspaceUpdate(SmartspaceSessionId sessionId) {
+// Log.d(TAG, "onRequestSmartspaceUpdate mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG){
+ Log.d(TAG, "onRequestSmartspaceUpdate sessionId=" + sessionId);
+ }
+ List<SmartspaceTarget> returnList = targets.get(sessionId);
+ if(returnList == null) {
+ returnList = new ArrayList<>();
+ }
+ updateSmartspaceTargets(sessionId, returnList);
+ sWatcher.verifier.onRequestSmartspaceUpdate(sessionId);
+ }
+
+ @Override
+ public void onDestroySmartspaceSession(SmartspaceSessionId sessionId) {
+// Log.d(TAG, "onDestroySmartspaceSession mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) Log.d(TAG, "onDestroySmartspaceSession");
+ targets.remove(sessionId);
+ super.onDestroy();
+ sWatcher.destroyed.countDown();
+ }
+
+ @Override
+ public void onDestroy(SmartspaceSessionId sessionId) {
+// Log.d(TAG, "onDestroy mSessionCallbacks: " + mSessionCallbacks);
+ if (DEBUG) Log.d(TAG, "onDestroy");
+ super.onDestroy();
+ sWatcher.destroyed.countDown();
+ }
+
+
+ public static Watcher setWatcher() {
+ if (DEBUG) {
+ Log.d(TAG, "");
+ Log.d(TAG, "----------------------------------------------");
+ Log.d(TAG, " setWatcher");
+ }
+ if (sWatcher != null) {
+ throw new IllegalStateException("Set watcher with watcher already set");
+ }
+ sWatcher = new Watcher();
+ return sWatcher;
+ }
+
+ public static void clearWatcher() {
+ if (DEBUG) Log.d(TAG, "clearWatcher");
+ sWatcher = null;
+ }
+
+ public static final class Watcher {
+ public CountDownLatch created = new CountDownLatch(1);
+ public CountDownLatch destroyed = new CountDownLatch(1);
+ public CountDownLatch queried = new CountDownLatch(1);
+ public CountDownLatch queriedTwice = new CountDownLatch(2);
+
+ /**
+ * Can be used to verify that API specific service methods are called. Not a real mock as
+ * the system isn't talking to this directly, it has calls proxied to it.
+ */
+ public CtsSmartspaceService verifier;
+
+ public List<SmartspaceTarget> mSmartspaceTargets;
+
+ public void setTargets(List<SmartspaceTarget> targets) {
+ mSmartspaceTargets = targets;
+ }
+ }
+}
diff --git a/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java b/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java
new file mode 100644
index 0000000..936a835
--- /dev/null
+++ b/tests/smartspace/src/android/smartspace/cts/SmartspaceManagerTest.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2020 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.smartspace.cts;
+
+import static androidx.test.InstrumentationRegistry.getContext;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.app.smartspace.SmartspaceConfig;
+import android.app.smartspace.SmartspaceManager;
+import android.app.smartspace.SmartspaceSession;
+import android.app.smartspace.SmartspaceTarget;
+import android.app.smartspace.SmartspaceTargetEvent;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Process;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.RequiredServiceRule;
+import com.android.compatibility.common.util.SystemUtil;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+/**
+ * Tests for {@link SmartspaceManager}
+ *
+ * atest CtsSearchUiServiceTestCases
+ */
+@RunWith(AndroidJUnit4.class)
+public class SmartspaceManagerTest {
+
+ private static final String TAG = "SmartspaceManagerTest";
+ private static final boolean DEBUG = false;
+
+ private static final long VERIFY_TIMEOUT_MS = 5_000;
+ private static final long SERVICE_LIFECYCLE_TIMEOUT_MS = 20_000;
+ private static final String TEST_UI_SURFACE = "homescreen";
+ private static final String SMARTSPACE_ACTION_ID = "dummy_action_id";
+ private static final int TEST_NUM_PREDICTIONS = 10;
+ private static final String TEST_LAUNCH_LOCATION = "testCollapsedLocation";
+ private static final int TEST_ACTION = 2;
+
+ @Rule
+ public final RequiredServiceRule mRequiredServiceRule =
+ new RequiredServiceRule(Context.SMARTSPACE_SERVICE);
+
+ private SmartspaceManager mManager;
+ private SmartspaceSession mClient;
+ private CtsSmartspaceService.Watcher mWatcher;
+
+ @Before
+ public void setUp() throws Exception {
+ mWatcher = CtsSmartspaceService.setWatcher();
+ mManager = getContext().getSystemService(SmartspaceManager.class);
+ setService(CtsSmartspaceService.SERVICE_NAME);
+ SmartspaceConfig config = createSmartspaceConfig(TEST_UI_SURFACE);
+ mClient = createSmartspaceSession(config);
+ await(mWatcher.created, "Waiting for onCreate()");
+ reset(mWatcher.verifier);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ Log.d(TAG, "Starting tear down, watcher is: " + mWatcher);
+ mClient.destroy();
+ setService(null);
+ await(mWatcher.destroyed, "Waiting for onDestroy()");
+
+ mWatcher = null;
+ CtsSmartspaceService.clearWatcher();
+ }
+
+ @Test
+ public void testCreateSmartspaceSession() {
+ assertNotNull(mClient);
+ assertNotNull(mWatcher.verifier);
+ }
+
+ @Test
+ public void testDestroySession() {
+ SmartspaceSession localClient = createSmartspaceSession(createSmartspaceConfig("surface"));
+ localClient.destroy();
+ await(mWatcher.destroyed, "Waiting for onDestroy()");
+ }
+
+ @Test
+ public void testRequestSmartspaceUpdate() {
+ // Send a request for a smartspace update
+ SmartspaceTarget testTarget = SmartspaceTestUtils.getBasicSmartspaceTarget("id",
+ SmartspaceTestUtils.getTestComponentName(), Process.myUserHandle());
+ SmartspaceTargetEvent testEvent = new SmartspaceTargetEvent.Builder(
+ SmartspaceTargetEvent.EVENT_TARGET_INTERACTION).setSmartspaceTarget(
+ testTarget).setSmartspaceActionId("id").build();
+ mClient.notifySmartspaceEvent(testEvent);
+ mClient.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+ targets -> {
+ if (targets.size() > 0 && targets.get(0).equals(testTarget)) {
+ mWatcher.queried.countDown();
+ }
+ });
+ mClient.requestSmartspaceUpdate();
+ // Verify that the API received it
+ verify(mWatcher.verifier, timeout(VERIFY_TIMEOUT_MS).times(2))
+ .onRequestSmartspaceUpdate(any());
+ await(mWatcher.queried, "Waiting for updateSmartspaceTargets()");
+ }
+
+ @Test
+ public void testRequestSmartspaceUpdateForMultipleSessions() {
+ SmartspaceTarget testTarget = SmartspaceTestUtils.getBasicSmartspaceTarget("id",
+ SmartspaceTestUtils.getTestComponentName(), Process.myUserHandle());
+ SmartspaceTargetEvent testEvent = new SmartspaceTargetEvent.Builder(
+ SmartspaceTargetEvent.EVENT_TARGET_INTERACTION).setSmartspaceTarget(
+ testTarget).setSmartspaceActionId("id").build();
+
+ SmartspaceConfig config1 = createSmartspaceConfig("surface 1");
+ SmartspaceSession client1 = createSmartspaceSession(config1);
+ SmartspaceConfig config2 = createSmartspaceConfig("surface 2");
+ SmartspaceSession client2 = createSmartspaceSession(config2);
+ client1.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+ targets -> {
+ // Counting down only if the returned list only contains test target.
+ if (targets.size() > 0 && targets.get(0).equals(testTarget)) {
+ mWatcher.queriedTwice.countDown();
+ }
+ });
+ client2.registerSmartspaceUpdates(Executors.newSingleThreadExecutor(),
+ targets -> {
+ // Counting down only if the returned list is empty.
+ if (targets.isEmpty()) {
+ mWatcher.queriedTwice.countDown();
+ }
+ });
+ // Notifying the event only for client1.
+ client1.notifySmartspaceEvent(testEvent);
+ // Requesting update for both the clients
+ client1.requestSmartspaceUpdate();
+ client2.requestSmartspaceUpdate();
+ // Verify that the API received it 4 times, twice for each client, once while registering
+ // and once while requesting.
+ verify(mWatcher.verifier, timeout(VERIFY_TIMEOUT_MS).times(4))
+ .onRequestSmartspaceUpdate(any());
+ await(mWatcher.queriedTwice, "Waiting for updateSmartspaceTargets() to be called twice");
+ }
+
+ @Test
+ public void testNotifySmartspaceEvent() {
+ ComponentName componentName = new ComponentName("package_name", "class_name");
+ SmartspaceTarget target = new SmartspaceTarget.Builder("id",
+ componentName, Process.myUserHandle()).build();
+
+ SmartspaceTargetEvent smartspaceTargetEvent = new SmartspaceTargetEvent.Builder(
+ SmartspaceTargetEvent.EVENT_TARGET_BLOCK).setSmartspaceActionId(
+ SMARTSPACE_ACTION_ID).setSmartspaceTarget(target).build();
+
+ ArgumentCaptor<SmartspaceTargetEvent> arg = ArgumentCaptor.forClass(
+ SmartspaceTargetEvent.class);
+ // Send a request to notifySmartspaceUpdate
+ mClient.notifySmartspaceEvent(smartspaceTargetEvent);
+ // Verify that the API received it.
+ verify(mWatcher.verifier, timeout(VERIFY_TIMEOUT_MS))
+ .notifySmartspaceEvent(any(), arg.capture());
+ assertEquals(arg.getValue().getSmartspaceActionId(), SMARTSPACE_ACTION_ID);
+ assertEquals(arg.getValue().getEventType(), SmartspaceTargetEvent.EVENT_TARGET_BLOCK);
+ assertEquals(arg.getValue().getSmartspaceTarget().getComponentName(), componentName);
+ assertEquals(arg.getValue().getSmartspaceTarget().getUserHandle(), Process.myUserHandle());
+ assertEquals(arg.getValue().getSmartspaceTarget().getSmartspaceTargetId(), "id");
+
+ }
+
+ private void setService(String service) {
+ Log.d(TAG, "Setting smartspace service to " + service);
+ int userId = Process.myUserHandle().getIdentifier();
+ if (service != null) {
+ runShellCommand("cmd smartspace set temporary-service "
+ + userId + " " + service + " 60000");
+ } else {
+ runShellCommand("cmd smartspace set temporary-service " + userId);
+ }
+ }
+
+ private SmartspaceSession createSmartspaceSession(SmartspaceConfig config) {
+ return mManager.createSmartspaceSession(config);
+ }
+
+ private SmartspaceConfig createSmartspaceConfig(String uiSurface) {
+ return new SmartspaceConfig.Builder(
+ InstrumentationRegistry.getTargetContext(),
+ uiSurface).setSmartspaceTargetCount(TEST_NUM_PREDICTIONS).build();
+ }
+
+ private void await(@NonNull CountDownLatch latch, @NonNull String message) {
+ try {
+ assertWithMessage(message).that(
+ latch.await(SERVICE_LIFECYCLE_TIMEOUT_MS, TimeUnit.MILLISECONDS)).isTrue();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ throw new IllegalStateException("Interrupted while: " + message);
+ }
+ }
+
+ private void runShellCommand(String command) {
+ Log.d(TAG, "runShellCommand(): " + command);
+ try {
+ SystemUtil.runShellCommand(InstrumentationRegistry.getInstrumentation(), command);
+ } catch (Exception e) {
+ throw new RuntimeException("Command '" + command + "' failed: ", e);
+ }
+ }
+
+ public static class ConsumerVerifier implements
+ Consumer<List<SmartspaceTarget>> {
+
+ private static List<SmartspaceTarget> mExpectedTargets;
+
+ public ConsumerVerifier(List<SmartspaceTarget> targets) {
+ mExpectedTargets = targets;
+ }
+
+ @Override
+ public void accept(List<SmartspaceTarget> actualTargets) {
+ if (DEBUG) {
+ Log.d(TAG, "ConsumerVerifier.accept targets.size= " + actualTargets.size());
+ Log.d(TAG, "ConsumerVerifier.accept target(1).packageName=" + actualTargets.get(
+ 0).getComponentName().getPackageName());
+ }
+ Assert.assertArrayEquals(actualTargets.toArray(), mExpectedTargets.toArray());
+ }
+ }
+
+ private static class RequestVerifier implements SmartspaceSession.Callback {
+ @Override
+ public void onTargetsAvailable(List<SmartspaceTarget> targets) {
+
+ }
+ }
+}
diff --git a/tests/smartspace/src/android/smartspace/cts/SmartspaceTestUtils.java b/tests/smartspace/src/android/smartspace/cts/SmartspaceTestUtils.java
new file mode 100644
index 0000000..d2a5ffb
--- /dev/null
+++ b/tests/smartspace/src/android/smartspace/cts/SmartspaceTestUtils.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.smartspace.cts;
+
+import android.app.smartspace.SmartspaceTarget;
+import android.content.ComponentName;
+import android.os.UserHandle;
+
+public class SmartspaceTestUtils {
+ public static SmartspaceTarget getBasicSmartspaceTarget(String id, ComponentName componentName, UserHandle userHandle){
+ return new SmartspaceTarget.Builder(id, componentName, userHandle).build();
+ }
+
+ public static ComponentName getTestComponentName() {
+ return new ComponentName("package name", "class name");
+ }
+}