diff --git a/services/CHANGELOG.md b/services/CHANGELOG.md index 5f06775b0..a0a81195e 100644 --- a/services/CHANGELOG.md +++ b/services/CHANGELOG.md @@ -2,14 +2,21 @@ {{date}} + `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 diff --git a/services/storage/java/androidx/test/services/storage/file/BUILD b/services/storage/java/androidx/test/services/storage/file/BUILD index 3100f6ee4..b8b498637 100644 --- a/services/storage/java/androidx/test/services/storage/file/BUILD +++ b/services/storage/java/androidx/test/services/storage/file/BUILD @@ -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", ], diff --git a/services/storage/java/androidx/test/services/storage/file/HostedFile.java b/services/storage/java/androidx/test/services/storage/file/HostedFile.java index 2f331a290..9ab09fd52 100644 --- a/services/storage/java/androidx/test/services/storage/file/HostedFile.java +++ b/services/storage/java/androidx/test/services/storage/file/HostedFile.java @@ -18,12 +18,9 @@ import android.content.Context; import android.net.Uri; 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; @@ -38,8 +35,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), @@ -152,21 +147,8 @@ 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(); - } 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(); - } + // Use a reliably self-writable directory. + return context.getExternalFilesDir(null); } private static T checkNotNull(T reference) { diff --git a/services/storage/java/androidx/test/services/storage/provider/InternalUseOnlyFilesContentProvider.java b/services/storage/java/androidx/test/services/storage/provider/InternalUseOnlyFilesContentProvider.java index eab13bbb1..2c47761f6 100644 --- a/services/storage/java/androidx/test/services/storage/provider/InternalUseOnlyFilesContentProvider.java +++ b/services/storage/java/androidx/test/services/storage/provider/InternalUseOnlyFilesContentProvider.java @@ -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); } diff --git a/services/storage/javatests/androidx/test/services/storage/BUILD b/services/storage/javatests/androidx/test/services/storage/BUILD index b817713a5..022317c6a 100644 --- a/services/storage/javatests/androidx/test/services/storage/BUILD +++ b/services/storage/javatests/androidx/test/services/storage/BUILD @@ -2,7 +2,7 @@ # Tests for the test storage. load("//build_extensions:android_library_test.bzl", "axt_android_library_test") -load("//build_extensions:phone_devices.bzl", "devices") +load("//build_extensions:phone_devices.bzl", "apis", "devices") package( default_applicable_licenses = ["//services:license"], @@ -30,10 +30,51 @@ 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", "@maven//:junit_junit", ], ) + +[ + axt_android_library_test( + name = "TestStorageHsumTest_{user}".format(user = user), + size = "large", + srcs = [ + "TestStorageTest.java", + ], + args = [ + "--install_test_services=true", + "--test_args=arg1=value1,arg2=value2,arg3=value3", + "--instrumentation_user={user}".format(user = user), + ], + data = [ + ":testinput.txt", + ], + device_list = + custom_devices( + apis(min_api = 36), + "hsum_phone", + "google_hsum", + "x86_64", + ), + support_apps = [ + "//services:test_services", + ], + tags = ["requires-mem:20g"], + test_class = "androidx.test.services.storage.TestStorageTest", + 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", + "@maven//:junit_junit", + ], + ) + for user in [ + "0", + "10", + ] +] diff --git a/services/storage/javatests/androidx/test/services/storage/TestStorageTest.java b/services/storage/javatests/androidx/test/services/storage/TestStorageTest.java index da8377501..66d7935f1 100644 --- a/services/storage/javatests/androidx/test/services/storage/TestStorageTest.java +++ b/services/storage/javatests/androidx/test/services/storage/TestStorageTest.java @@ -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; @@ -113,20 +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")) {