From 27fb0488c037caf391fae5ee1c79e078630577ad Mon Sep 17 00:00:00 2001 From: Ajinkya Chalke Date: Fri, 3 Mar 2023 16:13:54 +0000 Subject: [PATCH 1/3] Update screenshot class visibilities for app clips. Bug:269403503 Test: build Change-Id: Ib364c11bdf94d9364e52393722a5012614ee2a35 --- .../systemui/screenshot/ImageExporter.java | 22 ++++++++++--------- .../systemui/screenshot/ScreenshotEvent.java | 8 +------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java index c8c133774766e..7cfe2327f9925 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ImageExporter.java @@ -57,7 +57,8 @@ import java.util.concurrent.Executor; import javax.inject.Inject; -class ImageExporter { +/** A class to help with exporting screenshot to storage. */ +public class ImageExporter { private static final String TAG = LogConfig.logTag(ImageExporter.class); static final Duration PENDING_ENTRY_TTL = Duration.ofHours(24); @@ -90,7 +91,7 @@ class ImageExporter { private final FeatureFlags mFlags; @Inject - ImageExporter(ContentResolver resolver, FeatureFlags flags) { + public ImageExporter(ContentResolver resolver, FeatureFlags flags) { mResolver = resolver; mFlags = flags; } @@ -148,7 +149,7 @@ class ImageExporter { * * @return a listenable future result */ - ListenableFuture export(Executor executor, UUID requestId, Bitmap bitmap, + public ListenableFuture export(Executor executor, UUID requestId, Bitmap bitmap, UserHandle owner) { return export(executor, requestId, bitmap, ZonedDateTime.now(), owner); } @@ -181,13 +182,14 @@ class ImageExporter { ); } - static class Result { - Uri uri; - UUID requestId; - String fileName; - long timestamp; - CompressFormat format; - boolean published; + /** The result returned by the task exporting screenshots to storage. */ + public static class Result { + public Uri uri; + public UUID requestId; + public String fileName; + public long timestamp; + public CompressFormat format; + public boolean published; @Override public String toString() { diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java index fc94aed5336a0..7a62bae5b5ae8 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotEvent.java @@ -93,13 +93,7 @@ public enum ScreenshotEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "User has discarded the result of a long screenshot") SCREENSHOT_LONG_SCREENSHOT_EXIT(911), @UiEvent(doc = "A screenshot has been taken and saved to work profile") - SCREENSHOT_SAVED_TO_WORK_PROFILE(1240), - @UiEvent(doc = "Notes application triggered the screenshot for notes") - SCREENSHOT_FOR_NOTE_TRIGGERED(1308), - @UiEvent(doc = "User accepted the screenshot to be sent to the notes app") - SCREENSHOT_FOR_NOTE_ACCEPTED(1309), - @UiEvent(doc = "User cancelled the screenshot for notes app flow") - SCREENSHOT_FOR_NOTE_CANCELLED(1310); + SCREENSHOT_SAVED_TO_WORK_PROFILE(1240); private final int mId; From 618e47a27b290bf9af8273a671614e474807f6f5 Mon Sep 17 00:00:00 2001 From: Ajinkya Chalke Date: Fri, 3 Mar 2023 16:18:15 +0000 Subject: [PATCH 2/3] Update app clips package style. Bug: 269403503 Test: atest AppClipsActivityTest AppClipsTrampolineActivityTest AppClipsViewModelTest Change-Id: I41b84f07f528b49820bc5ba60d31bd9e5db6f687 --- .../dagger/DefaultActivityBinder.java | 4 +- .../systemui/notetask/NoteTaskEntryPoint.kt | 2 +- .../screenshot/appclips/AppClipsActivity.java | 18 +++++---- .../appclips/AppClipsCrossProcessHelper.java | 6 +-- .../screenshot/appclips/AppClipsEvent.java | 40 +++++++++++++++++++ .../AppClipsScreenshotHelperService.java | 1 - .../appclips/AppClipsTrampolineActivity.java | 4 +- .../appclips/AppClipsViewModel.java | 31 +++++--------- .../ScreenshotHardwareBufferInternal.java | 6 +-- .../appclips/AppClipsActivityTest.java | 7 +--- .../AppClipsTrampolineActivityTest.java | 8 ++-- .../appclips/AppClipsViewModelTest.java | 22 +++++----- 12 files changed, 86 insertions(+), 63 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsEvent.java diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java index a5beb4e85058d..ef7206d45ad59 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultActivityBinder.java @@ -23,9 +23,9 @@ import com.android.systemui.hdmi.HdmiCecSetMenuLanguageActivity; import com.android.systemui.keyguard.WorkLockActivity; import com.android.systemui.people.PeopleSpaceActivity; import com.android.systemui.people.widget.LaunchConversationActivity; -import com.android.systemui.screenshot.AppClipsActivity; -import com.android.systemui.screenshot.AppClipsTrampolineActivity; import com.android.systemui.screenshot.LongScreenshotActivity; +import com.android.systemui.screenshot.appclips.AppClipsActivity; +import com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity; import com.android.systemui.sensorprivacy.SensorUseStartedActivity; import com.android.systemui.sensorprivacy.television.TvSensorPrivacyChangedActivity; import com.android.systemui.sensorprivacy.television.TvUnblockSensorActivity; diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt index acc537a8eb369..2fa8f9a1e6fcf 100644 --- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt +++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskEntryPoint.kt @@ -17,7 +17,7 @@ package com.android.systemui.notetask import com.android.systemui.notetask.quickaffordance.NoteTaskQuickAffordanceConfig import com.android.systemui.notetask.shortcut.LaunchNoteTaskActivity -import com.android.systemui.screenshot.AppClipsTrampolineActivity +import com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity /** * Supported entry points for [NoteTaskController.showNoteTask]. diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java index 3133924339f28..4756cc8172e9b 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.android.systemui.screenshot; +package com.android.systemui.screenshot.appclips; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_NAME; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_RESULT_RECEIVER; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.PERMISSION_SELF; -import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_FOR_NOTE_ACCEPTED; -import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_FOR_NOTE_CANCELLED; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_ACCEPTED; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_CANCELLED; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.ACTION_FINISH_FROM_TRAMPOLINE; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_CALLING_PACKAGE_NAME; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_RESULT_RECEIVER; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.PERMISSION_SELF; import android.app.Activity; import android.content.BroadcastReceiver; @@ -52,6 +52,8 @@ import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLogger.UiEventEnum; import com.android.settingslib.Utils; import com.android.systemui.R; +import com.android.systemui.screenshot.CropView; +import com.android.systemui.screenshot.MagnifierView; import com.android.systemui.settings.UserTracker; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java index 65fb4c9bfb0d2..e1619dc9b6eef 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsCrossProcessHelper.java @@ -32,12 +32,12 @@ import javax.inject.Inject; /** An intermediary singleton object to help communicating with the cross process service. */ @SysUISingleton -public class AppClipsCrossProcessHelper { +class AppClipsCrossProcessHelper { private final ServiceConnector mProxyConnector; @Inject - public AppClipsCrossProcessHelper(@Application Context context) { + AppClipsCrossProcessHelper(@Application Context context) { mProxyConnector = new ServiceConnector.Impl(context, new Intent(context, AppClipsScreenshotHelperService.class), Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY @@ -52,7 +52,7 @@ public class AppClipsCrossProcessHelper { * pass around but not a {@link Bitmap}. */ @Nullable - public Bitmap takeScreenshot() { + Bitmap takeScreenshot() { try { AndroidFuture future = mProxyConnector.postForResult( diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsEvent.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsEvent.java new file mode 100644 index 0000000000000..7a085b9fd7d14 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 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 com.android.systemui.screenshot.appclips; + +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; + +enum AppClipsEvent implements UiEventLogger.UiEventEnum { + + @UiEvent(doc = "Notes application triggered the screenshot for notes") + SCREENSHOT_FOR_NOTE_TRIGGERED(1308), + @UiEvent(doc = "User accepted the screenshot to be sent to the notes app") + SCREENSHOT_FOR_NOTE_ACCEPTED(1309), + @UiEvent(doc = "User cancelled the screenshot for notes app flow") + SCREENSHOT_FOR_NOTE_CANCELLED(1310); + + private final int mId; + + AppClipsEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java index 6f8c36595c743..83ff020362f1a 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsScreenshotHelperService.java @@ -24,7 +24,6 @@ import android.window.ScreenCapture.ScreenshotSync; import androidx.annotation.Nullable; -import com.android.systemui.screenshot.AppClipsActivity; import com.android.wm.shell.bubbles.Bubbles; import java.util.Optional; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java index eda38e45c98a5..3cb1a34a921cb 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.screenshot; +package com.android.systemui.screenshot.appclips; import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_BLOCKED_BY_ADMIN; import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED; @@ -24,7 +24,7 @@ import static android.content.Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS; -import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_FOR_NOTE_TRIGGERED; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED; import android.app.Activity; import android.app.admin.DevicePolicyManager; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java index b2910fd488547..4cbca28a40322 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java @@ -14,12 +14,10 @@ * limitations under the License. */ -package com.android.systemui.screenshot; +package com.android.systemui.screenshot.appclips; import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED; -import static androidx.annotation.VisibleForTesting.PACKAGE_PRIVATE; - import android.content.Intent; import android.graphics.Bitmap; import android.graphics.HardwareRenderer; @@ -31,7 +29,6 @@ import android.net.Uri; import android.os.Process; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; @@ -39,11 +36,10 @@ import androidx.lifecycle.ViewModelProvider; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.screenshot.appclips.AppClipsCrossProcessHelper; +import com.android.systemui.screenshot.ImageExporter; import com.google.common.util.concurrent.ListenableFuture; -import java.time.ZonedDateTime; import java.util.UUID; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -52,8 +48,7 @@ import java.util.concurrent.Executor; import javax.inject.Inject; /** A {@link ViewModel} to help with the App Clips screenshot flow. */ -@VisibleForTesting(otherwise = PACKAGE_PRIVATE) -public final class AppClipsViewModel extends ViewModel { +final class AppClipsViewModel extends ViewModel { private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper; private final ImageExporter mImageExporter; @@ -80,8 +75,7 @@ public final class AppClipsViewModel extends ViewModel { } /** Grabs a screenshot and updates the {@link Bitmap} set in screenshot {@link LiveData}. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public void performScreenshot() { + void performScreenshot() { mBgExecutor.execute(() -> { Bitmap screenshot = mAppClipsCrossProcessHelper.takeScreenshot(); mMainExecutor.execute(() -> { @@ -95,14 +89,12 @@ public final class AppClipsViewModel extends ViewModel { } /** Returns a {@link LiveData} that holds the captured screenshot. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public LiveData getScreenshot() { + LiveData getScreenshot() { return mScreenshotLiveData; } /** Returns a {@link LiveData} that holds the {@link Uri} where screenshot is saved. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public LiveData getResultLiveData() { + LiveData getResultLiveData() { return mResultLiveData; } @@ -110,8 +102,7 @@ public final class AppClipsViewModel extends ViewModel { * Returns a {@link LiveData} that holds the error codes for * {@link Intent#EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE}. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public LiveData getErrorLiveData() { + LiveData getErrorLiveData() { return mErrorLiveData; } @@ -119,8 +110,7 @@ public final class AppClipsViewModel extends ViewModel { * Saves the provided {@link Drawable} to storage then informs the result {@link Uri} to * {@link LiveData}. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public void saveScreenshotThenFinish(Drawable screenshotDrawable, Rect bounds) { + void saveScreenshotThenFinish(Drawable screenshotDrawable, Rect bounds) { mBgExecutor.execute(() -> { // Render the screenshot bitmap in background. Bitmap screenshotBitmap = renderBitmap(screenshotDrawable, bounds); @@ -128,7 +118,7 @@ public final class AppClipsViewModel extends ViewModel { // Export and save the screenshot in background. // TODO(b/267310185): Save to work profile UserHandle. ListenableFuture exportFuture = mImageExporter.export( - mBgExecutor, UUID.randomUUID(), screenshotBitmap, ZonedDateTime.now(), + mBgExecutor, UUID.randomUUID(), screenshotBitmap, Process.myUserHandle()); // Get the result and update state on main thread. @@ -160,8 +150,7 @@ public final class AppClipsViewModel extends ViewModel { } /** Helper factory to help with injecting {@link AppClipsViewModel}. */ - @VisibleForTesting(otherwise = PACKAGE_PRIVATE) - public static final class Factory implements ViewModelProvider.Factory { + static final class Factory implements ViewModelProvider.Factory { private final AppClipsCrossProcessHelper mAppClipsCrossProcessHelper; private final ImageExporter mImageExporter; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java index 3b107f101088f..1e53ebb7935ee 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/ScreenshotHardwareBufferInternal.java @@ -28,7 +28,7 @@ import android.window.ScreenCapture.ScreenshotHardwareBuffer; * An internal version of {@link ScreenshotHardwareBuffer} that helps with parceling the information * necessary for creating a {@link Bitmap}. */ -public class ScreenshotHardwareBufferInternal implements Parcelable { +class ScreenshotHardwareBufferInternal implements Parcelable { public static final Creator CREATOR = new Creator<>() { @@ -45,7 +45,7 @@ public class ScreenshotHardwareBufferInternal implements Parcelable { private final HardwareBuffer mHardwareBuffer; private final ParcelableColorSpace mParcelableColorSpace; - public ScreenshotHardwareBufferInternal( + ScreenshotHardwareBufferInternal( ScreenshotHardwareBuffer screenshotHardwareBuffer) { mHardwareBuffer = screenshotHardwareBuffer.getHardwareBuffer(); mParcelableColorSpace = new ParcelableColorSpace( @@ -65,7 +65,7 @@ public class ScreenshotHardwareBufferInternal implements Parcelable { * {@link Bitmap#wrapHardwareBuffer(HardwareBuffer, ColorSpace)} and * {@link HardwareBuffer#close()} for more information. */ - public Bitmap createBitmapThenCloseBuffer() { + Bitmap createBitmapThenCloseBuffer() { Bitmap bitmap = Bitmap.wrapHardwareBuffer(mHardwareBuffer, mParcelableColorSpace.getColorSpace()); mHardwareBuffer.close(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java index 515e1ee172edd..9308c5f6c993c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java @@ -18,8 +18,8 @@ package com.android.systemui.screenshot.appclips; import static android.app.Activity.RESULT_OK; -import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_FOR_NOTE_ACCEPTED; -import static com.android.systemui.screenshot.ScreenshotEvent.SCREENSHOT_FOR_NOTE_CANCELLED; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_ACCEPTED; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_CANCELLED; import static com.google.common.truth.Truth.assertThat; @@ -50,9 +50,6 @@ import androidx.test.runner.intercepting.SingleActivityFactory; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; -import com.android.systemui.screenshot.AppClipsActivity; -import com.android.systemui.screenshot.AppClipsTrampolineActivity; -import com.android.systemui.screenshot.AppClipsViewModel; import com.android.systemui.settings.UserTracker; import org.junit.After; diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java index e40c49b56ac52..ad06dcc6f3278 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivityTest.java @@ -25,7 +25,8 @@ import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_WINDOW_MODE_UNSUPP import static android.content.Intent.EXTRA_CAPTURE_CONTENT_FOR_NOTE_STATUS_CODE; import static com.android.systemui.flags.Flags.SCREENSHOT_APP_CLIPS; -import static com.android.systemui.screenshot.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI; +import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_TRIGGERED; +import static com.android.systemui.screenshot.appclips.AppClipsTrampolineActivity.EXTRA_SCREENSHOT_URI; import static com.google.common.truth.Truth.assertThat; @@ -59,8 +60,6 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.notetask.NoteTaskController; -import com.android.systemui.screenshot.AppClipsTrampolineActivity; -import com.android.systemui.screenshot.ScreenshotEvent; import com.android.systemui.settings.UserTracker; import com.android.wm.shell.bubbles.Bubbles; @@ -262,8 +261,7 @@ public final class AppClipsTrampolineActivityTest extends SysuiTestCase { mActivityRule.launchActivity(mActivityIntent); waitForIdleSync(); - verify(mUiEventLogger).log(ScreenshotEvent.SCREENSHOT_FOR_NOTE_TRIGGERED, TEST_UID, - TEST_CALLING_PACKAGE); + verify(mUiEventLogger).log(SCREENSHOT_FOR_NOTE_TRIGGERED, TEST_UID, TEST_CALLING_PACKAGE); } private void mockToSatisfyAllPrerequisites() throws NameNotFoundException { diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java index d5af7ce1d346b..e7c3c05786278 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsViewModelTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.systemui.screenshot; +package com.android.systemui.screenshot.appclips; import static android.content.Intent.CAPTURE_CONTENT_FOR_NOTE_FAILED; @@ -36,7 +36,7 @@ import android.os.UserHandle; import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; -import com.android.systemui.screenshot.appclips.AppClipsCrossProcessHelper; +import com.android.systemui.screenshot.ImageExporter; import com.google.common.util.concurrent.Futures; @@ -46,7 +46,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; -import java.time.ZonedDateTime; import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; @@ -62,7 +61,7 @@ public final class AppClipsViewModelTest extends SysuiTestCase { @Mock private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper; @Mock private ImageExporter mImageExporter; - private com.android.systemui.screenshot.AppClipsViewModel mViewModel; + private AppClipsViewModel mViewModel; @Before public void setUp() { @@ -99,8 +98,8 @@ public final class AppClipsViewModelTest extends SysuiTestCase { @Test public void saveScreenshot_throwsError_shouldUpdateErrorWithFailed() { - when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any( - ZonedDateTime.class), any(UserHandle.class))).thenReturn( + when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), + any(UserHandle.class))).thenReturn( Futures.immediateFailedFuture(new ExecutionException(new Throwable()))); mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT); @@ -113,9 +112,9 @@ public final class AppClipsViewModelTest extends SysuiTestCase { @Test public void saveScreenshot_failsSilently_shouldUpdateErrorWithFailed() { - when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any( - ZonedDateTime.class), any(UserHandle.class))).thenReturn( - Futures.immediateFuture(new ImageExporter.Result())); + when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), + any(UserHandle.class))).thenReturn( + Futures.immediateFuture(new ImageExporter.Result())); mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT); waitForIdleSync(); @@ -129,9 +128,8 @@ public final class AppClipsViewModelTest extends SysuiTestCase { public void saveScreenshot_succeeds_shouldUpdateResultWithUri() { ImageExporter.Result result = new ImageExporter.Result(); result.uri = FAKE_URI; - when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), any( - ZonedDateTime.class), any(UserHandle.class))).thenReturn( - Futures.immediateFuture(result)); + when(mImageExporter.export(any(Executor.class), any(UUID.class), eq(null), + any(UserHandle.class))).thenReturn(Futures.immediateFuture(result)); mViewModel.saveScreenshotThenFinish(FAKE_DRAWABLE, FAKE_RECT); waitForIdleSync(); From 624782cc83f5859dcf973fd592046a0cd7363c7d Mon Sep 17 00:00:00 2001 From: Ajinkya Chalke Date: Wed, 22 Feb 2023 18:45:01 +0000 Subject: [PATCH 3/3] Update AppClipsActivityTest to use real ViewModel. - This fixes the flakiness issue with the ViewModel mock. Bug: 269403503 Test: atest AppClipsActivityTest --rerun-until-failure 100 Change-Id: I4a5621d2ab7f8cb11b974ba1e9f35c173b7a1157 --- .../appclips/AppClipsActivityTest.java | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java index 9308c5f6c993c..3c08d58cbb674 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/appclips/AppClipsActivityTest.java @@ -22,10 +22,10 @@ import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_ import static com.android.systemui.screenshot.appclips.AppClipsEvent.SCREENSHOT_FOR_NOTE_CANCELLED; import static com.google.common.truth.Truth.assertThat; +import static com.google.common.util.concurrent.MoreExecutors.directExecutor; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,33 +34,35 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.ApplicationInfoFlags; import android.graphics.Bitmap; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; import android.os.Parcel; import android.os.ResultReceiver; +import android.os.UserHandle; import android.testing.AndroidTestingRunner; import android.widget.ImageView; -import androidx.lifecycle.MutableLiveData; import androidx.test.rule.ActivityTestRule; import androidx.test.runner.intercepting.SingleActivityFactory; import com.android.internal.logging.UiEventLogger; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.screenshot.ImageExporter; import com.android.systemui.settings.UserTracker; +import com.google.common.util.concurrent.Futures; + import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import java.util.UUID; +import java.util.concurrent.Executor; import java.util.function.BiConsumer; @RunWith(AndroidTestingRunner.class) @@ -75,18 +77,16 @@ public final class AppClipsActivityTest extends SysuiTestCase { private static final String TEST_CALLING_PACKAGE = "test-calling-package"; @Mock - private AppClipsViewModel.Factory mViewModelFactory; + private AppClipsCrossProcessHelper mAppClipsCrossProcessHelper; + @Mock + private ImageExporter mImageExporter; @Mock private PackageManager mPackageManager; @Mock private UserTracker mUserTracker; @Mock private UiEventLogger mUiEventLogger; - @Mock - private AppClipsViewModel mViewModel; - private MutableLiveData mScreenshotLiveData; - private MutableLiveData mResultLiveData; private AppClipsActivity mActivity; // Using the deprecated ActivityTestRule and SingleActivityFactory to help with injecting mocks. @@ -94,8 +94,11 @@ public final class AppClipsActivityTest extends SysuiTestCase { new SingleActivityFactory<>(AppClipsActivityTestable.class) { @Override protected AppClipsActivityTestable create(Intent unUsed) { - return new AppClipsActivityTestable(mViewModelFactory, mPackageManager, - mUserTracker, mUiEventLogger); + return new AppClipsActivityTestable( + new AppClipsViewModel.Factory(mAppClipsCrossProcessHelper, + mImageExporter, getContext().getMainExecutor(), + directExecutor()), mPackageManager, mUserTracker, + mUiEventLogger); } }; @@ -107,29 +110,17 @@ public final class AppClipsActivityTest extends SysuiTestCase { public void setUp() throws PackageManager.NameNotFoundException { MockitoAnnotations.initMocks(this); - mScreenshotLiveData = new MutableLiveData<>(); - mResultLiveData = new MutableLiveData<>(); - MutableLiveData errorLiveData = new MutableLiveData<>(); - - when(mViewModelFactory.create(any(Class.class))).thenReturn(mViewModel); - when(mViewModel.getScreenshot()).thenReturn(mScreenshotLiveData); - when(mViewModel.getResultLiveData()).thenReturn(mResultLiveData); - when(mViewModel.getErrorLiveData()).thenReturn(errorLiveData); when(mUserTracker.getUserId()).thenReturn(TEST_USER_ID); - ApplicationInfo applicationInfo = new ApplicationInfo(); applicationInfo.uid = TEST_UID; when(mPackageManager.getApplicationInfoAsUser(eq(TEST_CALLING_PACKAGE), any(ApplicationInfoFlags.class), eq(TEST_USER_ID))).thenReturn(applicationInfo); - doAnswer(invocation -> { - runOnMainThread(() -> mScreenshotLiveData.setValue(TEST_BITMAP)); - return null; - }).when(mViewModel).performScreenshot(); - doAnswer(invocation -> { - runOnMainThread(() -> mResultLiveData.setValue(TEST_URI)); - return null; - }).when(mViewModel).saveScreenshotThenFinish(any(Drawable.class), any(Rect.class)); + when(mAppClipsCrossProcessHelper.takeScreenshot()).thenReturn(TEST_BITMAP); + ImageExporter.Result result = new ImageExporter.Result(); + result.uri = TEST_URI; + when(mImageExporter.export(any(Executor.class), any(UUID.class), any(Bitmap.class), + any(UserHandle.class))).thenReturn(Futures.immediateFuture(result)); } @After @@ -137,7 +128,6 @@ public final class AppClipsActivityTest extends SysuiTestCase { mActivityRule.finishActivity(); } - @Ignore("b/269403503") @Test public void appClipsLaunched_screenshotDisplayed() { launchActivity(); @@ -145,7 +135,6 @@ public final class AppClipsActivityTest extends SysuiTestCase { assertThat(((ImageView) mActivity.findViewById(R.id.preview)).getDrawable()).isNotNull(); } - @Ignore("b/269403503") @Test public void screenshotDisplayed_userConsented_screenshotExportedSuccessfully() { ResultReceiver resultReceiver = createResultReceiver((resultCode, data) -> { @@ -165,7 +154,6 @@ public final class AppClipsActivityTest extends SysuiTestCase { verify(mUiEventLogger).log(SCREENSHOT_FOR_NOTE_ACCEPTED, TEST_UID, TEST_CALLING_PACKAGE); } - @Ignore("b/269403503") @Test public void screenshotDisplayed_userDeclined() { ResultReceiver resultReceiver = createResultReceiver((resultCode, data) -> {