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

Commit 399e06d6 authored by Peiyong Lin's avatar Peiyong Lin
Browse files

Raise SurfaceControlFpsListener to System API.

Previously the SurfaceControlFpsListener is a hidden API which only
allows platform code access. This patch renames it to follow the
callback convention and raises it to be a system API in order to allow
system applications to access the FPS count of a task and its children.
The FPS count access is guarded by a permission ACCESS_FPS_COUNTER.

To follow the API convention and properly check the permission, the
register/unregister callback APIs are moved to WindowManager and
permission check is done in the System Server.

Minor: Rename to SurfaceControlFpsCallback to TaskFpsCallback in order
to follow the API naming convention.

Bug: b/199920468
CTS-Coverage-Bug: b/199920468
Test: atest TaskFpsCallbackTest
Change-Id: I6b0a0ad6500278b3da09059e9c2ede28d9a743aa
parent 53aa02dd
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ package android {
    field public static final String ACCESS_CONTEXT_HUB = "android.permission.ACCESS_CONTEXT_HUB";
    field public static final String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES";
    field @Deprecated public static final String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO";
    field public static final String ACCESS_FPS_COUNTER = "android.permission.ACCESS_FPS_COUNTER";
    field public static final String ACCESS_INSTANT_APPS = "android.permission.ACCESS_INSTANT_APPS";
    field public static final String ACCESS_LOCUS_ID_USAGE_STATS = "android.permission.ACCESS_LOCUS_ID_USAGE_STATS";
    field public static final String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION";
@@ -15206,6 +15207,8 @@ package android.view {
  public interface WindowManager extends android.view.ViewManager {
    method @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public android.graphics.Region getCurrentImeTouchRegion();
    method public default void registerTaskFpsCallback(@IntRange(from=0) int, @NonNull android.window.TaskFpsCallback);
    method public default void unregisterTaskFpsCallback(@NonNull android.window.TaskFpsCallback);
  }
  public static class WindowManager.LayoutParams extends android.view.ViewGroup.LayoutParams implements android.os.Parcelable {
@@ -15793,3 +15796,15 @@ package android.webkit {
}
package android.window {
  public final class TaskFpsCallback {
    ctor public TaskFpsCallback(@NonNull java.util.concurrent.Executor, @NonNull android.window.TaskFpsCallback.OnFpsCallbackListener);
  }
  public static interface TaskFpsCallback.OnFpsCallbackListener {
    method public void onFpsReported(float);
  }
}
+25 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ import android.view.WindowManager;
import android.view.SurfaceControl;
import android.view.displayhash.DisplayHash;
import android.view.displayhash.VerifiedDisplayHash;
import android.window.IOnFpsCallbackListener;

/**
 * System private interface to the window manager.
@@ -922,4 +923,28 @@ interface IWindowManager
     * reverts to using the default task transition with no spec changes.
     */
    void clearTaskTransitionSpec();

    /**
     * Registers the frame rate per second count callback for one given task ID.
     * Each callback can only register for receiving FPS callback for one task id until unregister
     * is called. If there's no task associated with the given task id,
     * {@link IllegalArgumentException} will be thrown. If a task id destroyed after a callback is
     * registered, the registered callback will not be unregistered until
     * {@link unregisterTaskFpsCallback()} is called
     * @param taskId task id of the task.
     * @param listener listener to be registered.
     *
     * @hide
     */
    void registerTaskFpsCallback(in int taskId, in IOnFpsCallbackListener listener);

    /**
     * Unregisters the frame rate per second count callback which was registered with
     * {@link #registerTaskFpsCallback(int,TaskFpsCallback)}.
     *
     * @param listener listener to be unregistered.
     *
     * @hide
     */
    void unregisterTaskFpsCallback(in IOnFpsCallbackListener listener);
}
+28 −0
Original line number Diff line number Diff line
@@ -118,6 +118,7 @@ import android.view.WindowInsets.Side.InsetsSide;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetsType;
import android.view.accessibility.AccessibilityNodeInfo;
import android.window.TaskFpsCallback;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -4858,4 +4859,31 @@ public interface WindowManager extends ViewManager {
    default boolean isTaskSnapshotSupported() {
        return false;
    }

    /**
     * Registers the frame rate per second count callback for one given task ID.
     * Each callback can only register for receiving FPS callback for one task id until unregister
     * is called. If there's no task associated with the given task id,
     * {@link IllegalArgumentException} will be thrown. If a task id destroyed after a callback is
     * registered, the registered callback will not be unregistered until
     * {@link #unregisterTaskFpsCallback(TaskFpsCallback))} is called
     * @param taskId task id of the task.
     * @param callback callback to be registered.
     *
     * @hide
     */
    @SystemApi
    default void registerTaskFpsCallback(@IntRange(from = 0) int taskId,
            @NonNull TaskFpsCallback callback) {}

    /**
     * Unregisters the frame rate per second count callback which was registered with
     * {@link #registerTaskFpsCallback(int,TaskFpsCallback)}.
     *
     * @param callback callback to be unregistered.
     *
     * @hide
     */
    @SystemApi
    default void unregisterTaskFpsCallback(@NonNull TaskFpsCallback callback) {}
}
+20 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
import static android.window.WindowProviderService.isWindowProviderService;

import android.annotation.CallbackExecutor;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiContext;
@@ -37,6 +38,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.StrictMode;
import android.window.TaskFpsCallback;
import android.window.WindowContext;
import android.window.WindowProvider;

@@ -419,4 +421,22 @@ public final class WindowManagerImpl implements WindowManager {
        }
        return false;
    }

    @Override
    public void registerTaskFpsCallback(@IntRange(from = 0) int taskId, TaskFpsCallback callback) {
        try {
            WindowManagerGlobal.getWindowManagerService().registerTaskFpsCallback(
                    taskId, callback.getListener());
        } catch (RemoteException e) {
        }
    }

    @Override
    public void unregisterTaskFpsCallback(TaskFpsCallback callback) {
        try {
            WindowManagerGlobal.getWindowManagerService().unregisterTaskFpsCallback(
                    callback.getListener());
        } catch (RemoteException e) {
        }
    }
}
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 * 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.
@@ -14,33 +14,17 @@
 * limitations under the License.
 */

package android.view;
package android.window;

import android.platform.test.annotations.Presubmit;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
@SmallTest
@Presubmit
public class SurfaceControlFpsListenerTest {

    @Test
    public void registersAndUnregisters() {

        SurfaceControlFpsListener listener = new SurfaceControlFpsListener() {
            @Override
            public void onFpsReported(float fps) {
                // Ignore
            }
        };

        listener.register(0);
/**
 * @hide
 */
oneway interface IOnFpsCallbackListener {

        listener.unregister();
    }
    /**
     * Reports the fps from the registered task
     * @param fps The frame rate per second of the task that has the registered task id
     *            and its children.
     */
    void onFpsReported(in float fps);
}
Loading