Merge "Expose Environment device/credential encrypted app storage directories"
This commit is contained in:
@@ -9703,6 +9703,8 @@ package android.os {
|
||||
}
|
||||
|
||||
public class Environment {
|
||||
method @NonNull public static java.io.File getDataCePackageDirectoryForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle, @NonNull String);
|
||||
method @NonNull public static java.io.File getDataDePackageDirectoryForUser(@NonNull java.util.UUID, @NonNull android.os.UserHandle, @NonNull String);
|
||||
method @NonNull public static java.util.Collection<java.io.File> getInternalMediaDirectories();
|
||||
method @NonNull public static java.io.File getOdmDirectory();
|
||||
method @NonNull public static java.io.File getOemDirectory();
|
||||
|
||||
@@ -2071,7 +2071,7 @@ package android.os.storage {
|
||||
|
||||
public class StorageManager {
|
||||
method public long computeStorageCacheBytes(@NonNull java.io.File);
|
||||
method @NonNull public static java.util.UUID convert(@NonNull String);
|
||||
method @NonNull public static java.util.UUID convert(@Nullable String);
|
||||
method @NonNull public static String convert(@NonNull java.util.UUID);
|
||||
method @Nullable public String getCloudMediaProvider();
|
||||
method public boolean isAppIoBlocked(@NonNull java.util.UUID, int, int, int);
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.os;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
@@ -44,6 +45,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Provides access to environment variables.
|
||||
@@ -551,12 +553,37 @@ public class Environment {
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static File getDataUserCePackageDirectory(String volumeUuid, int userId,
|
||||
String packageName) {
|
||||
@NonNull
|
||||
public static File getDataUserCePackageDirectory(@Nullable String volumeUuid, int userId,
|
||||
@NonNull String packageName) {
|
||||
// TODO: keep consistent with installd
|
||||
return new File(getDataUserCeDirectory(volumeUuid, userId), packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the credential encrypted data directory for a specific package of a specific user.
|
||||
* This is equivalent to {@link ApplicationInfo#credentialProtectedDataDir}, exposed because
|
||||
* fetching a full {@link ApplicationInfo} instance may be expensive if all the caller needs
|
||||
* is this directory.
|
||||
*
|
||||
* @param storageUuid The storage volume for this directory, usually retrieved from a
|
||||
* {@link StorageManager} API or {@link ApplicationInfo#storageUuid}.
|
||||
* @param user The user this directory is for.
|
||||
* @param packageName The app this directory is for.
|
||||
*
|
||||
* @see ApplicationInfo#credentialProtectedDataDir
|
||||
* @return A file to the directory.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
public static File getDataCePackageDirectoryForUser(@NonNull UUID storageUuid,
|
||||
@NonNull UserHandle user, @NonNull String packageName) {
|
||||
var volumeUuid = StorageManager.convert(storageUuid);
|
||||
return getDataUserCePackageDirectory(volumeUuid, user.getIdentifier(), packageName);
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static File getDataUserDeDirectory(String volumeUuid) {
|
||||
return new File(getDataDirectory(volumeUuid), DIR_USER_DE);
|
||||
@@ -568,12 +595,37 @@ public class Environment {
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public static File getDataUserDePackageDirectory(String volumeUuid, int userId,
|
||||
String packageName) {
|
||||
@NonNull
|
||||
public static File getDataUserDePackageDirectory(@Nullable String volumeUuid, int userId,
|
||||
@NonNull String packageName) {
|
||||
// TODO: keep consistent with installd
|
||||
return new File(getDataUserDeDirectory(volumeUuid, userId), packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the device encrypted data directory for a specific package of a specific user. This
|
||||
* is equivalent to {@link ApplicationInfo#deviceProtectedDataDir}, exposed because fetching a
|
||||
* full {@link ApplicationInfo} instance may be expensive if all the caller needs is this
|
||||
* directory.
|
||||
*
|
||||
* @param storageUuid The storage volume for this directory, usually retrieved from a
|
||||
* {@link StorageManager} API or {@link ApplicationInfo#storageUuid}.
|
||||
* @param user The user this directory is for.
|
||||
* @param packageName The app this directory is for.
|
||||
*
|
||||
* @see ApplicationInfo#deviceProtectedDataDir
|
||||
* @return A file to the directory.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@NonNull
|
||||
public static File getDataDePackageDirectoryForUser(@NonNull UUID storageUuid,
|
||||
@NonNull UserHandle user, @NonNull String packageName) {
|
||||
var volumeUuid = StorageManager.convert(storageUuid);
|
||||
return getDataUserDePackageDirectory(volumeUuid, user.getIdentifier(), packageName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return preloads directory.
|
||||
* <p>This directory may contain pre-loaded content such as
|
||||
|
||||
@@ -84,6 +84,15 @@
|
||||
"include-filter": "android.os.cts.SharedMemoryTest"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"file_patterns": ["Environment[^/]*\\.java"],
|
||||
"name": "FrameworksCoreTests",
|
||||
"options": [
|
||||
{
|
||||
"include-filter": "android.os.EnvironmentTest"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"postsubmit": [
|
||||
|
||||
@@ -2742,7 +2742,8 @@ public class StorageManager {
|
||||
|
||||
/** {@hide} */
|
||||
@TestApi
|
||||
public static @NonNull UUID convert(@NonNull String uuid) {
|
||||
public static @NonNull UUID convert(@Nullable String uuid) {
|
||||
// UUID_PRIVATE_INTERNAL is null, so this accepts nullable input
|
||||
if (Objects.equals(uuid, UUID_PRIVATE_INTERNAL)) {
|
||||
return UUID_DEFAULT;
|
||||
} else if (Objects.equals(uuid, UUID_PRIMARY_PHYSICAL)) {
|
||||
|
||||
@@ -22,12 +22,12 @@ import static android.os.Environment.HAS_DOWNLOADS;
|
||||
import static android.os.Environment.HAS_OTHER;
|
||||
import static android.os.Environment.classifyExternalStorageDirectory;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
import android.os.storage.StorageManager;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -38,6 +38,9 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class EnvironmentTest {
|
||||
@@ -104,4 +107,42 @@ public class EnvironmentTest {
|
||||
Environment.buildPath(dir, "Taxes.pdf").createNewFile();
|
||||
assertEquals(HAS_OTHER, classifyExternalStorageDirectory(dir));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataCePackageDirectoryForUser() {
|
||||
testDataPackageDirectoryForUser(
|
||||
(uuid, userHandle) -> Environment.getDataCePackageDirectoryForUser(
|
||||
uuid, userHandle, getContext().getPackageName()),
|
||||
(uuid, user) -> Environment.getDataUserCePackageDirectory(
|
||||
uuid, user, getContext().getPackageName())
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataDePackageDirectoryForUser() {
|
||||
testDataPackageDirectoryForUser(
|
||||
(uuid, userHandle) -> Environment.getDataDePackageDirectoryForUser(
|
||||
uuid, userHandle, getContext().getPackageName()),
|
||||
(uuid, user) -> Environment.getDataUserDePackageDirectory(
|
||||
uuid, user, getContext().getPackageName())
|
||||
);
|
||||
}
|
||||
|
||||
private void testDataPackageDirectoryForUser(
|
||||
BiFunction<UUID, UserHandle, File> publicApi,
|
||||
BiFunction<String, Integer, File> hideApi) {
|
||||
var uuids = new ArrayList<String>();
|
||||
uuids.add(null); // Private internal
|
||||
uuids.add("primary_physical");
|
||||
uuids.add("system");
|
||||
uuids.add("3939-3939"); // FAT Volume
|
||||
uuids.add("57554103-df3e-4475-ae7a-8feba49353ac"); // Random valid UUID
|
||||
var userHandle = UserHandle.of(0);
|
||||
|
||||
// Check that the @hide method is consistent with the public API
|
||||
for (String uuid : uuids) {
|
||||
assertThat(publicApi.apply(StorageManager.convert(uuid), userHandle))
|
||||
.isEqualTo(hideApi.apply(uuid, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user