Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions services/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@

{{date}}

<!-- disableFinding(LINE_OVER_80) -->
`androidx.test.services:test-services:{version}` `androidx.test.services:storage:{version}` are released.

**Bug Fixes**

* Ensure TestStorage library is multi-linux-user compatible.

**New Features**

**Breaking Changes**

* The location where TestStorage stores files has changed. This is non-breaking
if using the TestStorage API, but breaking if tests depended on the explicit
location of the files (e.g., by reading them without using TestStorage).

**API Changes**

* Update to minSdkVersion 23 and remove all related logic for SDKs < 23
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ android_library(
name = "file",
srcs = glob(["*.java"]),
deps = [
"//opensource/androidx:annotation",
"//runner/monitor",
"//services/storage/java/androidx/test/services/storage:test_storage_constants",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@

import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.UserManager;
import android.provider.OpenableColumns;
import android.util.Log;
import androidx.test.services.storage.TestStorageConstants;
import java.io.File;
import java.util.concurrent.atomic.AtomicBoolean;

import androidx.annotation.RestrictTo;
import androidx.annotation.RestrictTo.Scope;
Expand All @@ -38,8 +36,6 @@ public final class HostedFile {

private static final String TAG = "HostedFile";

private static final AtomicBoolean loggedOutputDir = new AtomicBoolean(false);

/** An enum of the columns returned by the hosted file service. */
public enum HostedFileColumn {
NAME("name", String.class, 3 /* Cursor.FIELD_TYPE_STRING since api 11 */, 0),
Expand Down Expand Up @@ -152,20 +148,11 @@ public static File getInputRootDirectory(Context context) {
}

public static File getOutputRootDirectory(Context context) {
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
if (userManager.isSystemUser()) {
return Environment.getExternalStorageDirectory();
// Use a reliably self-writable directory.
if (Build.VERSION.SDK_INT >= 29) {
return context.getExternalFilesDir(null);
} else {
// using legacy external storage for output in automotive devices where tests run as
// a secondary user has been flaky. So use local storage instead.
if (!loggedOutputDir.getAndSet(true)) {
// limit log spam by only logging choice once
Log.d(
TAG,
"Secondary user detected. Choosing local storage as output root dir: "
+ context.getCacheDir().getAbsolutePath());
}
return context.getCacheDir();
return Environment.getExternalStorageDirectory();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ android_library(
manifest = "AndroidManifest.xml",
deps = [
"//runner/monitor",
"//services/storage",
"//services/storage/java/androidx/test/services/storage:storage_service_pb_java_proto_lite",
"//services/storage/java/androidx/test/services/storage:test_storage_constants",
"//services/storage/java/androidx/test/services/storage/file",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ public final class InternalUseOnlyFilesContentProvider extends AbstractFileConte

@Override
protected File getHostedDirectory(Context context) {
// use input root directory here, as TestArgsContentProvider also uses this directory
// Uses the output root directory since the provider is Read/Write and only the output directory
// is guaranteed to be writable.
return new File(
HostedFile.getInputRootDirectory(context),
HostedFile.getOutputRootDirectory(context),
TestStorageConstants.ON_DEVICE_PATH_INTERNAL_USE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@
import android.net.Uri;
import android.util.Log;
import androidx.test.services.storage.TestStorageConstants;
import androidx.test.services.storage.TestStorageException;
import androidx.test.services.storage.TestStorageServiceProto.TestArgument;
import androidx.test.services.storage.TestStorageServiceProto.TestArguments;
import androidx.test.services.storage.file.HostedFile;
import androidx.test.services.storage.file.HostedFile.FileHost;
import androidx.test.services.storage.file.PropertyFile;
import androidx.test.services.storage.file.PropertyFile.Authority;
import androidx.test.services.storage.internal.TestStorageUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
Expand All @@ -48,17 +51,6 @@
public final class TestArgsContentProvider extends ContentProvider {

private static final String TAG = "TestArgCP";
private static final String ANDROID_TEST_SERVER_SPEC_FORMAT = "_server_address";

private static final String SYSTEM_PROPERTY_CLAZZ = "android.os.SystemProperties";
private static final String GET_METHOD = "get";

private String systemPropertyClassName;
private Method getString;

void setSystemPropertyClassNameForTest(String className) {
this.systemPropertyClassName = className;
}

@Override
public int delete(Uri arg0, String arg1, String[] arg2) {
Expand Down Expand Up @@ -119,13 +111,28 @@ private Map<String, String> buildArgMapFromFile() {
}

private static TestArguments readProtoFromFile(Context context) {
// File written by the InternalUseOnlyFilesContentProvider
Uri testArgsProtoUri =
HostedFile.buildUri(FileHost.INTERNAL_USE_ONLY, TestStorageConstants.TEST_ARGS_FILE_NAME);

try (InputStream testArgsProtoInputStream =
TestStorageUtil.getInputStream(testArgsProtoUri, context.getContentResolver())) {
Log.i(TAG, "Parsing test args from URI: " + testArgsProtoUri);
return TestArguments.parseFrom(testArgsProtoInputStream);
} catch (IOException | TestStorageException e) {
Log.i(
TAG,
"Test args file not found via URI: " + testArgsProtoUri + ". Checking file system...");
}

// File written directly to /sdcard/
File testArgsFile =
new File(
HostedFile.getInputRootDirectory(context),
TestStorageConstants.ON_DEVICE_PATH_INTERNAL_USE
+ TestStorageConstants.TEST_ARGS_FILE_NAME);
if (!testArgsFile.exists()) {
Log.i(TAG, "Test args file not found at " + testArgsFile.getAbsolutePath());
Log.i(TAG, "Test args file also not found at " + testArgsFile.getAbsolutePath());
return TestArguments.getDefaultInstance();
}
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ axt_android_library_test(
],
deps = [
"//core/java/androidx/test/core",
"//runner/monitor/java/androidx/test:monitor",
"//services/storage/java/androidx/test/services/storage",
"//services/storage/java/androidx/test/services/storage/file",
"@maven//:com_google_truth_truth",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,8 @@
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.TestCase.fail;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import android.content.Context;
import android.net.Uri;
import android.os.UserManager;
import androidx.test.services.storage.file.HostedFile;
import androidx.test.services.storage.internal.TestStorageUtil;
import java.io.BufferedReader;
Expand Down Expand Up @@ -113,19 +110,11 @@ public void addOutputProperties() throws Exception {

@Test
public void writeInternalFile() throws IOException {
// known not to work in multi-user mode
assumeTrue(isSystemUser());
try (OutputStream output = testStorage.openInternalOutputFile("path/to/file")) {
output.write(new byte[] {'h', 'e', 'l', 'l', 'o'});
}
}

private static boolean isSystemUser() {

UserManager um = ((UserManager) getApplicationContext().getSystemService(Context.USER_SERVICE));
return um.isSystemUser();
}

@Test
public void readWriteOverwriteReadFile() throws IOException {
try (OutputStream output = testStorage.openOutputFile("path/to/file")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@
import java.util.HashMap;
import java.util.Map;

/**
* Unit tests for {@link TestArgsContentProvider}.
*
* TODO(b/145236542): Converts the tests to JUnit4.
*/
/** Unit tests for {@link TestArgsContentProvider}. */
public class TestArgsContentProviderTest extends ProviderTestCase2<TestArgsContentProvider> {

private static final String[] ARGS = {"arg1", "arg2", "arg3", "someth_server_address"};
Expand All @@ -50,7 +46,6 @@ public TestArgsContentProviderTest() {
@Override
public void setUp() throws Exception {
super.setUp();
getProvider().setSystemPropertyClassNameForTest(FakeSystemProperties.class.getName());
}

@Override
Expand Down
Loading