Merge "Only honor passed-in userid value if work profile flag enabled" into tm-qpr-dev am: 6af3a82437 am: 3b0103fa77
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20303911 Change-Id: I004ad6a47d3b0402e4efbe7ef8633611a433c42c Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -38,6 +38,8 @@ import androidx.concurrent.futures.CallbackToFutureAdapter;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.flags.FeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
@@ -85,10 +87,12 @@ class ImageExporter {
|
||||
private final ContentResolver mResolver;
|
||||
private CompressFormat mCompressFormat = CompressFormat.PNG;
|
||||
private int mQuality = 100;
|
||||
private final FeatureFlags mFlags;
|
||||
|
||||
@Inject
|
||||
ImageExporter(ContentResolver resolver) {
|
||||
ImageExporter(ContentResolver resolver, FeatureFlags flags) {
|
||||
mResolver = resolver;
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +165,7 @@ class ImageExporter {
|
||||
ZonedDateTime captureTime, UserHandle owner) {
|
||||
|
||||
final Task task = new Task(mResolver, requestId, bitmap, captureTime, mCompressFormat,
|
||||
mQuality, /* publish */ true, owner);
|
||||
mQuality, /* publish */ true, owner, mFlags);
|
||||
|
||||
return CallbackToFutureAdapter.getFuture(
|
||||
(completer) -> {
|
||||
@@ -209,9 +213,11 @@ class ImageExporter {
|
||||
private final UserHandle mOwner;
|
||||
private final String mFileName;
|
||||
private final boolean mPublish;
|
||||
private final FeatureFlags mFlags;
|
||||
|
||||
Task(ContentResolver resolver, UUID requestId, Bitmap bitmap, ZonedDateTime captureTime,
|
||||
CompressFormat format, int quality, boolean publish, UserHandle owner) {
|
||||
CompressFormat format, int quality, boolean publish, UserHandle owner,
|
||||
FeatureFlags flags) {
|
||||
mResolver = resolver;
|
||||
mRequestId = requestId;
|
||||
mBitmap = bitmap;
|
||||
@@ -221,6 +227,7 @@ class ImageExporter {
|
||||
mOwner = owner;
|
||||
mFileName = createFilename(mCaptureTime, mFormat);
|
||||
mPublish = publish;
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
public Result execute() throws ImageExportException, InterruptedException {
|
||||
@@ -234,7 +241,7 @@ class ImageExporter {
|
||||
start = Instant.now();
|
||||
}
|
||||
|
||||
uri = createEntry(mResolver, mFormat, mCaptureTime, mFileName, mOwner);
|
||||
uri = createEntry(mResolver, mFormat, mCaptureTime, mFileName, mOwner, mFlags);
|
||||
throwIfInterrupted();
|
||||
|
||||
writeImage(mResolver, mBitmap, mFormat, mQuality, uri);
|
||||
@@ -278,13 +285,15 @@ class ImageExporter {
|
||||
}
|
||||
|
||||
private static Uri createEntry(ContentResolver resolver, CompressFormat format,
|
||||
ZonedDateTime time, String fileName, UserHandle owner) throws ImageExportException {
|
||||
ZonedDateTime time, String fileName, UserHandle owner, FeatureFlags flags)
|
||||
throws ImageExportException {
|
||||
Trace.beginSection("ImageExporter_createEntry");
|
||||
try {
|
||||
final ContentValues values = createMetadata(time, format, fileName);
|
||||
|
||||
Uri baseUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
if (UserHandle.myUserId() != owner.getIdentifier()) {
|
||||
if (flags.isEnabled(Flags.SCREENSHOT_WORK_PROFILE_POLICY)
|
||||
&& UserHandle.myUserId() != owner.getIdentifier()) {
|
||||
baseUri = ContentProvider.maybeAddUserId(baseUri, owner.getIdentifier());
|
||||
}
|
||||
Uri uri = resolver.insert(baseUri, values);
|
||||
|
||||
@@ -1043,8 +1043,13 @@ public class ScreenshotController {
|
||||
}
|
||||
|
||||
private boolean isUserSetupComplete(UserHandle owner) {
|
||||
return Settings.Secure.getInt(mContext.createContextAsUser(owner, 0)
|
||||
.getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
|
||||
if (mFlags.isEnabled(SCREENSHOT_WORK_PROFILE_POLICY)) {
|
||||
return Settings.Secure.getInt(mContext.createContextAsUser(owner, 0)
|
||||
.getContentResolver(), SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
|
||||
} else {
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
SETTINGS_SECURE_USER_SETUP_COMPLETE, 0) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
import android.content.ContentProvider;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -31,9 +32,11 @@ import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.MediaStore;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
@@ -41,11 +44,18 @@ import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.test.filters.MediumTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.flags.FakeFeatureFlags;
|
||||
import com.android.systemui.flags.Flags;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
@@ -60,7 +70,6 @@ import java.util.concurrent.Executor;
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@MediumTest // file I/O
|
||||
public class ImageExporterTest extends SysuiTestCase {
|
||||
|
||||
/** Executes directly in the caller's thread */
|
||||
private static final Executor DIRECT_EXECUTOR = Runnable::run;
|
||||
private static final byte[] EXIF_FILE_TAG = "Exif\u0000\u0000".getBytes(US_ASCII);
|
||||
@@ -68,6 +77,15 @@ public class ImageExporterTest extends SysuiTestCase {
|
||||
private static final ZonedDateTime CAPTURE_TIME =
|
||||
ZonedDateTime.of(LocalDateTime.of(2020, 12, 15, 13, 15), ZoneId.of("EST"));
|
||||
|
||||
private FakeFeatureFlags mFeatureFlags = new FakeFeatureFlags();
|
||||
@Mock
|
||||
private ContentResolver mMockContentResolver;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImageFilename() {
|
||||
assertEquals("image file name", "Screenshot_20201215-131500.png",
|
||||
@@ -92,7 +110,8 @@ public class ImageExporterTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testImageExport() throws ExecutionException, InterruptedException, IOException {
|
||||
ContentResolver contentResolver = mContext.getContentResolver();
|
||||
ImageExporter exporter = new ImageExporter(contentResolver);
|
||||
mFeatureFlags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, true);
|
||||
ImageExporter exporter = new ImageExporter(contentResolver, mFeatureFlags);
|
||||
|
||||
UUID requestId = UUID.fromString("3c11da99-9284-4863-b1d5-6f3684976814");
|
||||
Bitmap original = createCheckerBitmap(10, 10, 10);
|
||||
@@ -168,6 +187,44 @@ public class ImageExporterTest extends SysuiTestCase {
|
||||
values.getAsLong(MediaStore.MediaColumns.DATE_EXPIRES));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUser() {
|
||||
mFeatureFlags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, true);
|
||||
ImageExporter exporter = new ImageExporter(mMockContentResolver, mFeatureFlags);
|
||||
|
||||
UserHandle imageUserHande = UserHandle.of(10);
|
||||
|
||||
ArgumentCaptor<Uri> uriCaptor = ArgumentCaptor.forClass(Uri.class);
|
||||
// Capture the URI and then return null to bail out of export.
|
||||
Mockito.when(mMockContentResolver.insert(uriCaptor.capture(), Mockito.any())).thenReturn(
|
||||
null);
|
||||
exporter.export(DIRECT_EXECUTOR, UUID.fromString("3c11da99-9284-4863-b1d5-6f3684976814"),
|
||||
null, CAPTURE_TIME, imageUserHande);
|
||||
|
||||
Uri expected = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
expected = ContentProvider.maybeAddUserId(expected, imageUserHande.getIdentifier());
|
||||
|
||||
assertEquals(expected, uriCaptor.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetUser_noWorkProfile() {
|
||||
mFeatureFlags.set(Flags.SCREENSHOT_WORK_PROFILE_POLICY, false);
|
||||
ImageExporter exporter = new ImageExporter(mMockContentResolver, mFeatureFlags);
|
||||
|
||||
UserHandle imageUserHandle = UserHandle.of(10);
|
||||
|
||||
ArgumentCaptor<Uri> uriCaptor = ArgumentCaptor.forClass(Uri.class);
|
||||
// Capture the URI and then return null to bail out of export.
|
||||
Mockito.when(mMockContentResolver.insert(uriCaptor.capture(), Mockito.any())).thenReturn(
|
||||
null);
|
||||
exporter.export(DIRECT_EXECUTOR, UUID.fromString("3c11da99-9284-4863-b1d5-6f3684976814"),
|
||||
null, CAPTURE_TIME, imageUserHandle);
|
||||
|
||||
// The user handle should be ignored here since the flag is off.
|
||||
assertEquals(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, uriCaptor.getValue());
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
private Bitmap createCheckerBitmap(int tileSize, int w, int h) {
|
||||
Bitmap bitmap = Bitmap.createBitmap(w * tileSize, h * tileSize, Bitmap.Config.ARGB_8888);
|
||||
|
||||
@@ -62,7 +62,7 @@ import org.mockito.Mockito.verifyZeroInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
private const val USER_ID = 1
|
||||
private const val TASK_ID = 1
|
||||
private const val TASK_ID = 11
|
||||
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@SmallTest
|
||||
|
||||
Reference in New Issue
Block a user