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

Commit 9c6db630 authored by Chris Göllner's avatar Chris Göllner Committed by samcackett
Browse files

[Partial Screenshare] log projection permission cancelled

Log an atom for when a user cancels media projection i.e. cancels or dismisses the projection request dialog

Bug: 304726296
Test: atest FrameworksServicesTests:MediaProjectionManagerServiceTest
Test: atest FrameworksServicesTests:MediaProjectionMetricsLoggerTest
Test: atest SystemUITests:ScreenRecordPermissionDialogTest
Flag: LEGACY enable_record_task_content ENABLED
Change-Id: I2877cfa8dd4a8150452653292f6c058cf8e0e276
parent 01fc16e6
Loading
Loading
Loading
Loading
+8 −15
Original line number Diff line number Diff line
@@ -158,15 +158,12 @@ interface IMediaProjectionManager {
            in @nullable IMediaProjection projection);

    /**
     * Notifies system server that we are handling a particular state during the consent flow.
     * Notifies system server that the permission request was initiated.
     *
     * <p>Only used for emitting atoms.
     *
     * @param hostUid               The uid of the process requesting consent to capture, may be an app or
     *                              SystemUI.
     * @param state                 The state that SystemUI is handling during the consent flow.
     *                              Must be a valid
     *                              state defined in the MediaProjectionState enum.
     * @param sessionCreationSource Only set if the state is MEDIA_PROJECTION_STATE_INITIATED.
     *                              Indicates the entry point for requesting the permission. Must be
     *                              a valid state defined
@@ -175,27 +172,23 @@ interface IMediaProjectionManager {
    @EnforcePermission("android.Manifest.permission.MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    oneway void notifyPermissionRequestStateChange(int hostUid, int state, int sessionCreationSource);
    oneway void notifyPermissionRequestInitiated(int hostUid, int sessionCreationSource);

    /**
     * Notifies system server that the permission request was initiated.
     * Notifies system server that the permission request was displayed.
     *
     * <p>Only used for emitting atoms.
     *
     * @param hostUid The uid of the process requesting consent to capture, may be an app or
     *                SystemUI.
     * @param sessionCreationSource Only set if the state is MEDIA_PROJECTION_STATE_INITIATED.
     *                              Indicates the entry point for requesting the permission. Must be
     *                              a valid state defined
     *                              in the SessionCreationSource enum.
     */
    @EnforcePermission("android.Manifest.permission.MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    oneway void notifyPermissionRequestInitiated(int hostUid, int sessionCreationSource);
    oneway void notifyPermissionRequestDisplayed(int hostUid);

    /**
     * Notifies system server that the permission request was displayed.
     * Notifies system server that the permission request was cancelled.
     *
     * <p>Only used for emitting atoms.
     *
@@ -205,7 +198,7 @@ interface IMediaProjectionManager {
    @EnforcePermission("android.Manifest.permission.MANAGE_MEDIA_PROJECTION")
    @JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
            + ".permission.MANAGE_MEDIA_PROJECTION)")
    oneway void notifyPermissionRequestDisplayed(int hostUid);
    oneway void notifyPermissionRequestCancelled(int hostUid);

    /**
     * Notifies system server that the app selector was displayed.
+9 −38
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package com.android.systemui.mediaprojection

import android.media.projection.IMediaProjectionManager
import android.os.Process
import android.os.RemoteException
import android.util.Log
import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__CREATION_SOURCE__CREATION_SOURCE_APP as METRICS_CREATION_SOURCE_APP
@@ -66,56 +65,28 @@ constructor(private val service: IMediaProjectionManager) {
    }

    /**
     * Request to log that the app selector was displayed.
     * Request to log that the permission request was cancelled.
     *
     * @param hostUid The UID of the package that initiates MediaProjection.
     */
    fun notifyAppSelectorDisplayed(hostUid: Int) {
    fun notifyProjectionRequestCancelled(hostUid: Int) {
        try {
            service.notifyAppSelectorDisplayed(hostUid)
            service.notifyPermissionRequestCancelled(hostUid)
        } catch (e: RemoteException) {
            Log.e(TAG, "Error notifying server of app selector displayed", e)
        }
            Log.e(TAG, "Error notifying server of projection cancelled", e)
        }

    /**
     * Request to log that the permission request moved to the given state.
     *
     * Should not be used for the initialization state, since that should use {@link
     * MediaProjectionMetricsLogger#notifyProjectionInitiated(Int)} and pass the
     * sessionCreationSource.
     */
    fun notifyPermissionProgress(state: Int) {
        // TODO validate state is valid
        notifyToServer(state, SessionCreationSource.UNKNOWN)
    }

    /**
     * Notifies system server that we are handling a particular state during the consent flow.
     *
     * Only used for emitting atoms.
     * Request to log that the app selector was displayed.
     *
     * @param state The state that SystemUI is handling during the consent flow. Must be a valid
     *   state defined in the MediaProjectionState enum.
     * @param sessionCreationSource Only set if the state is MEDIA_PROJECTION_STATE_INITIATED.
     *   Indicates the entry point for requesting the permission. Must be a valid state defined in
     *   the SessionCreationSource enum.
     * @param hostUid The UID of the package that initiates MediaProjection.
     */
    private fun notifyToServer(state: Int, sessionCreationSource: SessionCreationSource) {
        Log.v(TAG, "FOO notifyToServer of state $state and source $sessionCreationSource")
    fun notifyAppSelectorDisplayed(hostUid: Int) {
        try {
            service.notifyPermissionRequestStateChange(
                Process.myUid(),
                state,
                sessionCreationSource.toMetricsConstant()
            )
            service.notifyAppSelectorDisplayed(hostUid)
        } catch (e: RemoteException) {
            Log.e(
                TAG,
                "Error notifying server of permission flow state $state from source " +
                    "$sessionCreationSource",
                e
            )
            Log.e(TAG, "Error notifying server of app selector displayed", e)
        }
    }

+4 −0
Original line number Diff line number Diff line
@@ -210,6 +210,10 @@ class MediaProjectionAppSelectorActivity(
                reviewGrantedConsentRequired,
                /* projection= */ null
            )
            if (isFinishing) {
                // Only log dismissed when actually finishing, and not when changing configuration.
                controller.onSelectorDismissed()
            }
        }
        activityLauncher.destroy()
        controller.destroy()
+4 −1
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.systemui.mediaprojection.appselector

import android.content.ComponentName
import android.os.UserHandle
import com.android.internal.util.FrameworkStatsLog.MEDIA_PROJECTION_STATE_CHANGED__STATE__MEDIA_PROJECTION_STATE_APP_SELECTOR_DISPLAYED as STATE_APP_SELECTOR_DISPLAYED
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.mediaprojection.appselector.data.RecentTask
import com.android.systemui.mediaprojection.appselector.data.RecentTaskListProvider
@@ -76,6 +75,10 @@ constructor(
        scope.cancel()
    }

    fun onSelectorDismissed() {
        logger.notifyProjectionRequestCancelled(hostUid)
    }

    private suspend fun refreshForegroundTaskThumbnails(tasks: List<RecentTask>) {
        coroutineScope {
            val thumbnails: List<Deferred<ThumbnailData?>> =
+17 −1
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
import com.android.systemui.res.R
import com.android.systemui.statusbar.phone.SystemUIDialog

@@ -40,16 +41,31 @@ open class BaseScreenSharePermissionDialog(
    context: Context,
    private val screenShareOptions: List<ScreenShareOption>,
    private val appName: String?,
    private val hostUid: Int,
    private val mediaProjectionMetricsLogger: MediaProjectionMetricsLogger,
    @DrawableRes private val dialogIconDrawable: Int? = null,
    @ColorRes private val dialogIconTint: Int? = null
    @ColorRes private val dialogIconTint: Int? = null,
) : SystemUIDialog(context), AdapterView.OnItemSelectedListener {
    private lateinit var dialogTitle: TextView
    private lateinit var startButton: TextView
    private lateinit var cancelButton: TextView
    private lateinit var warning: TextView
    private lateinit var screenShareModeSpinner: Spinner
    private var hasCancelBeenLogged: Boolean = false
    var selectedScreenShareOption: ScreenShareOption = screenShareOptions.first()

    override fun dismiss() {
        super.dismiss()

        // Dismiss can be called multiple times and we only want to log once.
        if (hasCancelBeenLogged) {
            return
        }

        mediaProjectionMetricsLogger.notifyProjectionRequestCancelled(hostUid)
        hasCancelBeenLogged = true
    }

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window?.addPrivateFlags(WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS)
Loading