Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea7c33f7 authored by Mark Renouf's avatar Mark Renouf
Browse files

Initial work profile screenshot policy handling

When a request is received, screen contents are inspected
to determine the most appropriate owner. If the primary
content belongs to a work profile app, the screenshot will
be isolated to the task content.

See: go/work-profile-screenshots for details.

This change also enables the foreground app package name to
be provided with uievent logging.

Additional functionality to follow.

To activate, enable the flag WORK_PROFILE_SCREENSHOT_POLICY

  adb shell cmd statusbar flag 1301 on

This also requires the flag SCREENSHOTS_REQUEST_PROCESSOR

  adb shell cmd statusbar flag 1300 on

Bug: 159422805
Bug: 231957192
Bug: 200294244
Test: atest RequestProcessorTest
      manual; enable flags,
      take screenshot of launcher
      take screenshot of work profile app
      observe logs and screenshot content
Change-Id: Idc74b04ddd449bfd9765ab9a456e9f9344c3aa2c
parent a53fd2a5
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -394,6 +394,11 @@
                  android:label="@string/screenshot_scroll_label"
                  android:finishOnTaskLaunch="true" />

        <service android:name=".screenshot.ScreenshotProxyService"
                 android:permission="com.android.systemui.permission.SELF"
                 android:exported="false" />


        <service android:name=".screenrecord.RecordingService" />

        <receiver android:name=".SysuiRestartReceiver"
+1 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ public class Flags {
    // 1300 - screenshots

    public static final UnreleasedFlag SCREENSHOT_REQUEST_PROCESSOR = new UnreleasedFlag(1300);
    public static final UnreleasedFlag SCREENSHOT_WORK_PROFILE_POLICY = new UnreleasedFlag(1301);

    // Pay no attention to the reflection behind the curtain.
    // ========================== Curtain ==========================
+24 −0
Original line number Diff line number Diff line
/**
 * Copyright (c) 2009, 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;

/** Interface implemented by ScreenshotProxyService */
interface IScreenshotProxy {

    /** Is the notification shade currently exanded? */
    boolean isNotificationShadeExpanded();
}
 No newline at end of file
+1 −1
Original line number Diff line number Diff line
@@ -22,5 +22,5 @@ interface ImageCapture {

    fun captureDisplay(displayId: Int, crop: Rect? = null): Bitmap?

    fun captureTask(taskId: Int): Bitmap?
    suspend fun captureTask(taskId: Int): Bitmap?
}
+20 −9
Original line number Diff line number Diff line
@@ -27,13 +27,19 @@ import android.view.SurfaceControl
import android.view.SurfaceControl.DisplayCaptureArgs
import android.view.SurfaceControl.ScreenshotHardwareBuffer
import androidx.annotation.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext

private const val TAG = "ImageCaptureImpl"

@SysUISingleton
open class ImageCaptureImpl @Inject constructor(
    private val displayManager: DisplayManager,
    private val atmService: IActivityTaskManager
    private val atmService: IActivityTaskManager,
    @Background private val bgContext: CoroutineDispatcher
) : ImageCapture {

    override fun captureDisplay(displayId: Int, crop: Rect?): Bitmap? {
@@ -46,8 +52,8 @@ open class ImageCaptureImpl @Inject constructor(
        return buffer?.asBitmap()
    }

    override fun captureTask(taskId: Int): Bitmap? {
        val snapshot = atmService.takeTaskSnapshot(taskId)
    override suspend fun captureTask(taskId: Int): Bitmap? {
        val snapshot = withContext(bgContext) { atmService.takeTaskSnapshot(taskId) } ?: return null
        return Bitmap.wrapHardwareBuffer(snapshot.hardwareBuffer, snapshot.colorSpace)
    }

@@ -67,12 +73,17 @@ open class ImageCaptureImpl @Inject constructor(
    }

    @VisibleForTesting
    open fun captureDisplay(displayToken: IBinder, width: Int, height: Int, crop: Rect): ScreenshotHardwareBuffer? {
        val captureArgs = DisplayCaptureArgs.Builder(displayToken)
    open fun captureDisplay(
        displayToken: IBinder,
        width: Int,
        height: Int,
        crop: Rect
    ): ScreenshotHardwareBuffer? {
        val captureArgs =
            DisplayCaptureArgs.Builder(displayToken)
                .setSize(width, height)
                .setSourceCrop(crop)
                .build()
        return SurfaceControl.captureDisplay(captureArgs)
    }

}
Loading