blob: c9f7fbb89978d3e08b48633254dc20c828f92b8d [file] [log] [blame]
/*
* 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.
*/
package android.contentsuggestions.cts;
import static androidx.test.InstrumentationRegistry.getContext;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
import android.app.contentsuggestions.ClassificationsRequest;
import android.app.contentsuggestions.ContentSuggestionsManager;
import android.app.contentsuggestions.SelectionsRequest;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.test.runner.AndroidJUnit4;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Tests for {@link ContentSuggestionsManager}.
*/
@RunWith(AndroidJUnit4.class)
public class ContentSuggestionsManagerTest {
private static final String TAG = ContentSuggestionsManagerTest.class.getSimpleName();
private static final long VERIFY_TIMEOUT_MS = 5_000;
private static final long SERVICE_LIFECYCLE_TIMEOUT_MS = 10_000;
private ContentSuggestionsManager mManager;
private CtsContentSuggestionsService.Watcher mWatcher;
@Before
public void setup() {
mWatcher = CtsContentSuggestionsService.setWatcher();
mManager = (ContentSuggestionsManager) getContext()
.getSystemService(Context.CONTENT_SUGGESTIONS_SERVICE);
setService(CtsContentSuggestionsService.SERVICE_COMPONENT.flattenToString());
// TODO: b/126587631 remove when the manager calls no longer need this.
getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
"android.permission.READ_FRAME_BUFFER");
// The ContentSuggestions services are created lazily, have to call one method on it to
// start the service for the tests.
mManager.notifyInteraction("SETUP", new Bundle());
await(mWatcher.created, "Waiting for create");
reset(mWatcher.verifier);
}
@After
public void tearDown() {
resetService();
await(mWatcher.destroyed, "Waiting for service destroyed");
mWatcher = null;
CtsContentSuggestionsService.clearWatcher();
// TODO: b/126587631 remove when the manager calls no longer need this.
getInstrumentation().getUiAutomation().dropShellPermissionIdentity();
}
@Test
public void managerForwards_notifyInteraction() {
String requestId = "TEST";
mManager.notifyInteraction(requestId, new Bundle());
verifyService().onNotifyInteraction(eq(requestId), any());
}
@Test
public void managerForwards_provideContextImage() {
int taskId = 1;
mManager.provideContextImage(taskId, new Bundle());
verifyService().onProcessContextImage(eq(taskId), any(), any());
}
@Test
public void managerForwards_suggestContentSelections() {
SelectionsRequest request = new SelectionsRequest.Builder(1).build();
ContentSuggestionsManager.SelectionsCallback callback = (statusCode, selections) -> {};
mManager.suggestContentSelections(request, Executors.newSingleThreadExecutor(), callback);
verifyService().onSuggestContentSelections(any(), any());
}
@Test
public void managerForwards_classifyContentSelections() {
ClassificationsRequest request = new ClassificationsRequest.Builder(
Lists.newArrayList()).build();
ContentSuggestionsManager.ClassificationsCallback callback =
(statusCode, classifications) -> {};
mManager.classifyContentSelections(request, Executors.newSingleThreadExecutor(), callback);
verifyService().onClassifyContentSelections(any(), any());
}
private CtsContentSuggestionsService verifyService() {
return verify(mWatcher.verifier, timeout(VERIFY_TIMEOUT_MS));
}
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);
}
}
/**
* Sets the content capture service.
*/
private static void setService(@NonNull String service) {
Log.d(TAG, "Setting service to " + service);
int userId = android.os.Process.myUserHandle().getIdentifier();
runShellCommand(
"cmd content_suggestions set temporary-service %d %s 120000", userId, service);
}
private static void resetService() {
Log.d(TAG, "Resetting service");
int userId = android.os.Process.myUserHandle().getIdentifier();
runShellCommand("cmd content_suggestions set temporary-service %d", userId);
}
}