summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/aconfig/systemui.aconfig10
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt40
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt62
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotRequestProcessor.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt28
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt184
7 files changed, 18 insertions, 324 deletions
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index 97206de346c5..1ce171609e5b 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -606,16 +606,6 @@ flag {
}
flag {
- name: "screenshot_private_profile_behavior_fix"
- namespace: "systemui"
- description: "Private profile support for screenshots"
- bug: "327613051"
- metadata {
- purpose: PURPOSE_BUGFIX
- }
-}
-
-flag {
name: "screenshot_save_image_exporter"
namespace: "systemui"
description: "Save all screenshots using ImageExporter"
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
index 474afa8bcb9d..56afb79c40d4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MessageContainerController.kt
@@ -9,7 +9,6 @@ import android.view.ViewGroup.MarginLayoutParams
import android.view.ViewTreeObserver
import android.view.animation.AccelerateDecelerateInterpolator
import androidx.constraintlayout.widget.Guideline
-import com.android.systemui.Flags.screenshotPrivateProfileBehaviorFix
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.res.R
import com.android.systemui.screenshot.message.ProfileMessageController
@@ -49,44 +48,19 @@ constructor(
}
fun onScreenshotTaken(screenshot: ScreenshotData) {
- if (screenshotPrivateProfileBehaviorFix()) {
- mainScope.launch {
- val profileData = profileMessageController.onScreenshotTaken(screenshot.userHandle)
- var notifiedApps: List<CharSequence> =
- screenshotDetectionController.maybeNotifyOfScreenshot(screenshot)
-
- // If profile first run needs to show, bias towards that, otherwise show screenshot
- // detection notification if needed.
- if (profileData != null) {
- workProfileFirstRunView.visibility = View.VISIBLE
- detectionNoticeView.visibility = View.GONE
- profileMessageController.bindView(workProfileFirstRunView, profileData) {
- animateOutMessageContainer()
- }
- animateInMessageContainer()
- } else if (notifiedApps.isNotEmpty()) {
- detectionNoticeView.visibility = View.VISIBLE
- workProfileFirstRunView.visibility = View.GONE
- screenshotDetectionController.populateView(detectionNoticeView, notifiedApps)
- animateInMessageContainer()
- }
- }
- } else {
- val workProfileData =
- workProfileMessageController.onScreenshotTaken(screenshot.userHandle)
+ mainScope.launch {
+ val profileData = profileMessageController.onScreenshotTaken(screenshot.userHandle)
var notifiedApps: List<CharSequence> =
screenshotDetectionController.maybeNotifyOfScreenshot(screenshot)
- // If work profile first run needs to show, bias towards that, otherwise show screenshot
+ // If profile first run needs to show, bias towards that, otherwise show screenshot
// detection notification if needed.
- if (workProfileData != null) {
+ if (profileData != null) {
workProfileFirstRunView.visibility = View.VISIBLE
detectionNoticeView.visibility = View.GONE
- workProfileMessageController.populateView(
- workProfileFirstRunView,
- workProfileData,
- this::animateOutMessageContainer
- )
+ profileMessageController.bindView(workProfileFirstRunView, profileData) {
+ animateOutMessageContainer()
+ }
animateInMessageContainer()
} else if (notifiedApps.isNotEmpty()) {
detectionNoticeView.visibility = View.VISIBLE
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
deleted file mode 100644
index 922997d08c25..000000000000
--- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2022 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
-
-import android.util.Log
-import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
-
-/** Implementation of [ScreenshotRequestProcessor] */
-class RequestProcessor(
- private val capture: ImageCapture,
- private val policy: ScreenshotPolicy,
-) : ScreenshotRequestProcessor {
-
- override suspend fun process(screenshot: ScreenshotData): ScreenshotData {
- var result = screenshot
-
- // Apply work profile screenshots policy:
- //
- // If the focused app belongs to a work profile, transforms a full screen
- // (or partial) screenshot request to a task snapshot (provided image) screenshot.
-
- // Whenever displayContentInfo is fetched, the topComponent is also populated
- // regardless of the managed profile status.
-
- if (screenshot.type != TAKE_SCREENSHOT_PROVIDED_IMAGE) {
- val info = policy.findPrimaryContent(screenshot.displayId)
- Log.d(TAG, "findPrimaryContent: $info")
- result.taskId = info.taskId
- result.topComponent = info.component
- result.userHandle = info.user
-
- if (policy.isManagedProfile(info.user.identifier)) {
- val image =
- capture.captureTask(info.taskId)
- ?: throw RequestProcessorException("Task snapshot returned a null Bitmap!")
-
- // Provide the task snapshot as the screenshot
- result.type = TAKE_SCREENSHOT_PROVIDED_IMAGE
- result.bitmap = image
- result.screenBounds = info.bounds
- }
- }
-
- return result
- }
-}
-
-private const val TAG = "RequestProcessor"
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotRequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotRequestProcessor.kt
index 3ad4075a2b89..ee1008d26414 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotRequestProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotRequestProcessor.kt
@@ -27,5 +27,5 @@ fun interface ScreenshotRequestProcessor {
suspend fun process(original: ScreenshotData): ScreenshotData
}
-/** Exception thrown by [RequestProcessor] if something goes wrong. */
+/** Exception thrown by [ScreenshotRequestProcessor] if something goes wrong. */
class RequestProcessorException(message: String) : IllegalStateException(message)
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt b/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
index 44f767aa321e..2cb9fe7f1a9d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/policy/ScreenshotPolicyModule.kt
@@ -19,14 +19,11 @@ package com.android.systemui.screenshot.policy
import android.content.ComponentName
import android.content.Context
import android.os.Process
-import com.android.systemui.Flags.screenshotPrivateProfileBehaviorFix
import com.android.systemui.SystemUIService
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.screenshot.ImageCapture
-import com.android.systemui.screenshot.RequestProcessor
-import com.android.systemui.screenshot.ScreenshotPolicy
import com.android.systemui.screenshot.ScreenshotRequestProcessor
import com.android.systemui.screenshot.data.repository.DisplayContentRepository
import com.android.systemui.screenshot.data.repository.DisplayContentRepositoryImpl
@@ -68,23 +65,18 @@ interface ScreenshotPolicyModule {
@Application context: Context,
@Background background: CoroutineDispatcher,
imageCapture: ImageCapture,
- policyProvider: Provider<ScreenshotPolicy>,
- displayContentRepoProvider: Provider<DisplayContentRepository>,
+ displayContentRepo: DisplayContentRepository,
policyListProvider: Provider<List<CapturePolicy>>,
): ScreenshotRequestProcessor {
- return if (screenshotPrivateProfileBehaviorFix()) {
- PolicyRequestProcessor(
- background = background,
- capture = imageCapture,
- displayTasks = displayContentRepoProvider.get(),
- policies = policyListProvider.get(),
- defaultOwner = Process.myUserHandle(),
- defaultComponent =
- ComponentName(context.packageName, SystemUIService::class.java.toString())
- )
- } else {
- RequestProcessor(imageCapture, policyProvider.get())
- }
+ return PolicyRequestProcessor(
+ background = background,
+ capture = imageCapture,
+ displayTasks = displayContentRepo,
+ policies = policyListProvider.get(),
+ defaultOwner = Process.myUserHandle(),
+ defaultComponent =
+ ComponentName(context.packageName, SystemUIService::class.java.toString())
+ )
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
index b31d21e7f8b2..15da77dfe33d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/MessageContainerControllerTest.kt
@@ -2,8 +2,6 @@ package com.android.systemui.screenshot
import android.graphics.drawable.Drawable
import android.os.UserHandle
-import android.platform.test.annotations.DisableFlags
-import android.platform.test.annotations.EnableFlags
import android.view.View
import android.view.ViewGroup
import android.widget.FrameLayout
@@ -90,20 +88,6 @@ class MessageContainerControllerTest : SysuiTestCase() {
}
@Test
- @DisableFlags(com.android.systemui.Flags.FLAG_SCREENSHOT_PRIVATE_PROFILE_BEHAVIOR_FIX)
- fun testOnScreenshotTakenUserHandle_withWorkProfileFirstRun() {
- whenever(workProfileMessageController.onScreenshotTaken(eq(userHandle)))
- .thenReturn(workProfileData)
- messageContainer.onScreenshotTaken(screenshotData)
-
- verify(workProfileMessageController)
- .populateView(eq(workProfileFirstRunView), eq(workProfileData), any())
- assertEquals(View.VISIBLE, workProfileFirstRunView.visibility)
- assertEquals(View.GONE, detectionNoticeView.visibility)
- }
-
- @Test
- @EnableFlags(com.android.systemui.Flags.FLAG_SCREENSHOT_PRIVATE_PROFILE_BEHAVIOR_FIX)
fun testOnScreenshotTakenUserHandle_withProfileProfileFirstRun() = runTest {
val profileData =
ProfileMessageController.ProfileFirstRunData(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
deleted file mode 100644
index 0847f01f12d3..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * Copyright (C) 2022 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
-
-import android.content.ComponentName
-import android.graphics.Bitmap
-import android.graphics.ColorSpace
-import android.graphics.Insets
-import android.graphics.Rect
-import android.hardware.HardwareBuffer
-import android.os.UserHandle
-import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_OTHER
-import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER
-import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN
-import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE
-import com.android.internal.util.ScreenshotRequest
-import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.runBlocking
-import org.junit.Assert
-import org.junit.Test
-
-private const val USER_ID = 1
-private const val TASK_ID = 1
-
-class RequestProcessorTest {
- private val imageCapture = FakeImageCapture()
- private val component = ComponentName("android.test", "android.test.Component")
- private val bounds = Rect(25, 25, 75, 75)
-
- private val policy = FakeScreenshotPolicy()
-
- @Test
- fun testFullScreenshot() = runBlocking {
- // Indicate that the primary content belongs to a normal user
- policy.setManagedProfile(USER_ID, false)
- policy.setDisplayContentInfo(
- policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)
- )
-
- val request =
- ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_OTHER).build()
- val processor = RequestProcessor(imageCapture, policy)
-
- val processedData = processor.process(ScreenshotData.fromRequest(request))
-
- // Request has topComponent added, but otherwise unchanged.
- assertThat(processedData.type).isEqualTo(TAKE_SCREENSHOT_FULLSCREEN)
- assertThat(processedData.source).isEqualTo(SCREENSHOT_OTHER)
- assertThat(processedData.topComponent).isEqualTo(component)
- }
-
- @Test
- fun testFullScreenshot_managedProfile() = runBlocking {
- // Provide a fake task bitmap when asked
- val bitmap = makeHardwareBitmap(100, 100)
- imageCapture.image = bitmap
-
- // Indicate that the primary content belongs to a manged profile
- policy.setManagedProfile(USER_ID, true)
- policy.setDisplayContentInfo(
- policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)
- )
-
- val request =
- ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build()
- val processor = RequestProcessor(imageCapture, policy)
-
- val processedData = processor.process(ScreenshotData.fromRequest(request))
-
- // Expect a task snapshot is taken, overriding the full screen mode
- assertThat(processedData.type).isEqualTo(TAKE_SCREENSHOT_PROVIDED_IMAGE)
- assertThat(processedData.bitmap).isEqualTo(bitmap)
- assertThat(processedData.screenBounds).isEqualTo(bounds)
- assertThat(processedData.insets).isEqualTo(Insets.NONE)
- assertThat(processedData.taskId).isEqualTo(TASK_ID)
- assertThat(imageCapture.requestedTaskId).isEqualTo(TASK_ID)
- }
-
- @Test
- fun testFullScreenshot_managedProfile_nullBitmap() {
- // Provide a null task bitmap when asked
- imageCapture.image = null
-
- // Indicate that the primary content belongs to a manged profile
- policy.setManagedProfile(USER_ID, true)
- policy.setDisplayContentInfo(
- policy.getDefaultDisplayId(),
- DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)
- )
-
- val request =
- ScreenshotRequest.Builder(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_OTHER).build()
- val processor = RequestProcessor(imageCapture, policy)
-
- Assert.assertThrows(IllegalStateException::class.java) {
- runBlocking { processor.process(ScreenshotData.fromRequest(request)) }
- }
- }
-
- @Test
- fun testProvidedImageScreenshot() = runBlocking {
- val bounds = Rect(50, 50, 150, 150)
- val processor = RequestProcessor(imageCapture, policy)
-
- policy.setManagedProfile(USER_ID, false)
-
- val bitmap = makeHardwareBitmap(100, 100)
-
- val request =
- ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
- .setTopComponent(component)
- .setTaskId(TASK_ID)
- .setUserId(USER_ID)
- .setBitmap(bitmap)
- .setBoundsOnScreen(bounds)
- .setInsets(Insets.NONE)
- .build()
-
- val screenshotData = ScreenshotData.fromRequest(request)
- val processedData = processor.process(screenshotData)
-
- assertThat(processedData).isEqualTo(screenshotData)
- }
-
- @Test
- fun testProvidedImageScreenshot_managedProfile() = runBlocking {
- val bounds = Rect(50, 50, 150, 150)
- val processor = RequestProcessor(imageCapture, policy)
-
- // Indicate that the screenshot belongs to a manged profile
- policy.setManagedProfile(USER_ID, true)
-
- val bitmap = makeHardwareBitmap(100, 100)
-
- val request =
- ScreenshotRequest.Builder(TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_OTHER)
- .setTopComponent(component)
- .setTaskId(TASK_ID)
- .setUserId(USER_ID)
- .setBitmap(bitmap)
- .setBoundsOnScreen(bounds)
- .setInsets(Insets.NONE)
- .build()
-
- val screenshotData = ScreenshotData.fromRequest(request)
- val processedData = processor.process(screenshotData)
-
- // Work profile, but already a task snapshot, so no changes
- assertThat(processedData).isEqualTo(screenshotData)
- }
-
- private fun makeHardwareBitmap(width: Int, height: Int): Bitmap {
- val buffer =
- HardwareBuffer.create(
- width,
- height,
- HardwareBuffer.RGBA_8888,
- 1,
- HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE
- )
- return Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB))!!
- }
-
- private fun Bitmap.equalsHardwareBitmap(bitmap: Bitmap): Boolean {
- return bitmap.hardwareBuffer == this.hardwareBuffer && bitmap.colorSpace == this.colorSpace
- }
-}