blob: 7fc3a68578d6f8c5b1b76e6ca4f8076c65136b34 [file] [log] [blame]
/*
* Copyright (C) 2018 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.contentcaptureservice.cts;
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.compatibility.common.util.ShellUtils.runShellCommand;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
import android.view.contentcapture.ContentCaptureSession;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.compatibility.common.util.Timeout;
import com.android.compatibility.common.util.UserSettings;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
/**
* Helper for common funcionalities.
*/
public final class Helper {
public static final String TAG = "ContentCaptureTest";
public static final long GENERIC_TIMEOUT_MS = 10_000;
public static final String MY_PACKAGE = "android.contentcaptureservice.cts";
public static final String MY_SECOND_PACKAGE = "android.contentcaptureservice.cts2";
public static final String OTHER_PACKAGE = "NOT.android.contentcaptureservice.cts";
public static final String EXTRA_VERIFY_RESULT = "verify_result";
public static final Set<String> NO_PACKAGES = null;
public static final Set<ComponentName> NO_ACTIVITIES = null;
public static final long MY_EPOCH = SystemClock.uptimeMillis();
public static final String RESOURCE_STRING_SERVICE_NAME = "config_defaultContentCaptureService";
public static final Context sContext = getInstrumentation().getTargetContext();
public static final UserSettings sUserSettings = new UserSettings(sContext);
private static final Timeout MY_TIMEOUT = new Timeout("MY_TIMEOUT", GENERIC_TIMEOUT_MS, 2F,
GENERIC_TIMEOUT_MS);
/**
* Awaits for a latch to be counted down.
*/
public static void await(@NonNull CountDownLatch latch, @NonNull String fmt,
@Nullable Object... args)
throws InterruptedException {
final boolean called = latch.await(GENERIC_TIMEOUT_MS, TimeUnit.MILLISECONDS);
if (!called) {
throw new IllegalStateException(String.format(fmt, args)
+ " in " + GENERIC_TIMEOUT_MS + "ms");
}
}
/**
* Sets the content capture service.
*/
public static void setService(@NonNull String service) {
final int userId = getCurrentUserId();
Log.d(TAG, "Setting service for user " + userId + " to " + service);
// TODO(b/123540602): use @TestingAPI to get max duration constant
runShellCommand("cmd content_capture set temporary-service %d %s 30000", userId, service);
}
/**
* Resets the content capture service.
*/
public static void resetService() {
final int userId = getCurrentUserId();
Log.d(TAG, "Resetting back user " + userId + " to default service");
runShellCommand("cmd content_capture set temporary-service %d", userId);
}
/**
* Enables / disables the default service.
*/
public static void setDefaultServiceEnabled(boolean enabled) {
final int userId = getCurrentUserId();
Log.d(TAG, "setDefaultServiceEnabled(user=" + userId + ", enabled= " + enabled + ")");
runShellCommand("cmd content_capture set default-service-enabled %d %s", userId,
Boolean.toString(enabled));
}
/**
* Gets the component name for a given class.
*/
public static ComponentName componentNameFor(@NonNull Class<?> clazz) {
return new ComponentName(MY_PACKAGE, clazz.getName());
}
/**
* Creates a view that can be added to a parent and is important for content capture
*/
public static TextView newImportantView(@NonNull Context context, @NonNull String text) {
final TextView child = new TextView(context);
child.setText(text);
child.setImportantForContentCapture(View.IMPORTANT_FOR_CONTENT_CAPTURE_YES);
Log.v(TAG, "newImportantView(text=" + text + ", id=" + child.getAutofillId() + ")");
return child;
}
/**
* Creates a view that can be added to a parent and is important for content capture
*/
public static TextView newImportantView(@NonNull Context context,
@NonNull ContentCaptureSession session, @NonNull String text) {
final TextView child = newImportantView(context, text);
child.setContentCaptureSession(session);
return child;
}
/**
* Gets a string from the Android resources.
*/
public static String getInternalString(@NonNull String id) {
final Resources resources = sContext.getResources();
final int stringId = resources.getIdentifier(id, "string", "android");
return resources.getString(stringId);
}
/**
* Runs an {@code assertion}, retrying until {@link #MY_TIMEOUT} is reached.
*/
public static <T> T eventually(@NonNull String description, @NonNull Callable<T> assertion)
throws Exception {
return MY_TIMEOUT.run(description, assertion);
}
/**
* Creates a Set with the given objects.
*/
public static <T> ArraySet<T> toSet(@SuppressWarnings("unchecked") @Nullable T... objs) {
final ArraySet<T> set = new ArraySet<>();
if (objs != null) {
for (int i = 0; i < objs.length; i++) {
final T t = objs[i];
set.add(t);
}
}
return set;
}
/**
* Gets the content of the given file.
*/
public static String read(@NonNull File file) throws IOException {
Log.d(TAG, "Reading " + file);
final byte[] bytes = Files.readAllBytes(Paths.get(file.getAbsolutePath()));
return bytes == null ? null : new String(bytes);
}
private static int getCurrentUserId() {
return UserHandle.myUserId();
}
private Helper() {
throw new UnsupportedOperationException("contain static methods only");
}
}