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

Commit 463b66a1 authored by Oleg Blinnikov's avatar Oleg Blinnikov Committed by Android (Google) Code Review
Browse files

Merge "Add ExternalDisplay metrics logging" into main

parents 1c9032ec e2c76219
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -430,6 +430,13 @@ public abstract class DisplayManagerInternal {
     */
    public abstract IntArray getDisplayGroupIds();

    /**
     * Called upon presentation started/ended on the display.
     * @param displayId the id of the display where presentation started.
     * @param isShown whether presentation is shown.
     */
    public abstract void onPresentation(int displayId, boolean isShown);

    /**
     * Describes the requested power state of the display.
     *
+24 −3
Original line number Diff line number Diff line
@@ -534,6 +534,7 @@ public final class DisplayManagerService extends SystemService {
    private final DisplayManagerFlags mFlags;

    private final DisplayNotificationManager mDisplayNotificationManager;
    private final ExternalDisplayStatsService mExternalDisplayStatsService;

    /**
     * Applications use {@link android.view.Display#getRefreshRate} and
@@ -568,7 +569,6 @@ public final class DisplayManagerService extends SystemService {
        mInjector = injector;
        mContext = context;
        mFlags = injector.getFlags();
        mDisplayNotificationManager = new DisplayNotificationManager(mFlags, mContext);
        mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
        mUiHandler = UiThread.getHandler();
        mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
@@ -597,6 +597,10 @@ public final class DisplayManagerService extends SystemService {
        mConfigParameterProvider = new DeviceConfigParameterProvider(DeviceConfigInterface.REAL);
        mExtraDisplayLoggingPackageName = DisplayProperties.debug_vri_package().orElse(null);
        mExtraDisplayEventLogging = !TextUtils.isEmpty(mExtraDisplayLoggingPackageName);

        mExternalDisplayStatsService = new ExternalDisplayStatsService(mContext, mHandler);
        mDisplayNotificationManager = new DisplayNotificationManager(mFlags, mContext,
                mExternalDisplayStatsService);
        mExternalDisplayPolicy = new ExternalDisplayPolicy(new ExternalDisplayPolicyInjector());
    }

@@ -1911,6 +1915,7 @@ public final class DisplayManagerService extends SystemService {
            return;
        }
        releaseDisplayAndEmitEvent(display, DisplayManagerGlobal.EVENT_DISPLAY_DISCONNECTED);
        mExternalDisplayPolicy.handleLogicalDisplayDisconnectedLocked(display);
    }

    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
@@ -1977,7 +1982,7 @@ public final class DisplayManagerService extends SystemService {

        setupLogicalDisplay(display);

        if (ExternalDisplayPolicy.isExternalDisplay(display)) {
        if (ExternalDisplayPolicy.isExternalDisplayLocked(display)) {
            mExternalDisplayPolicy.handleExternalDisplayConnectedLocked(display);
        } else {
            sendDisplayEventLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_CONNECTED);
@@ -2002,6 +2007,8 @@ public final class DisplayManagerService extends SystemService {
        sendDisplayEventIfEnabledLocked(display, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);

        updateLogicalDisplayState(display);

        mExternalDisplayPolicy.handleLogicalDisplayAddedLocked(display);
    }

    private void handleLogicalDisplayChangedLocked(@NonNull LogicalDisplay display) {
@@ -3280,7 +3287,7 @@ public final class DisplayManagerService extends SystemService {
            final var logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId);
            if (logicalDisplay == null) {
                Slog.w(TAG, "enableConnectedDisplay: Can not find displayId=" + displayId);
            } else if (ExternalDisplayPolicy.isExternalDisplay(logicalDisplay)) {
            } else if (ExternalDisplayPolicy.isExternalDisplayLocked(logicalDisplay)) {
                mExternalDisplayPolicy.setExternalDisplayEnabledLocked(logicalDisplay, enabled);
            } else {
                mLogicalDisplayMapper.setDisplayEnabledLocked(logicalDisplay, enabled);
@@ -4966,6 +4973,11 @@ public final class DisplayManagerService extends SystemService {
                return session;
            }
        }

        @Override
        public void onPresentation(int displayId, boolean isShown) {
            mExternalDisplayPolicy.onPresentation(displayId, isShown);
        }
    }

    class DesiredDisplayModeSpecsObserver
@@ -5123,5 +5135,14 @@ public final class DisplayManagerService extends SystemService {
        public Handler getHandler() {
            return mHandler;
        }

        /**
         * Gets service used for metrics collection.
         */
        @Override
        @NonNull
        public ExternalDisplayStatsService getExternalDisplayStatsService() {
            return mExternalDisplayStatsService;
        }
    }
}
+64 −4
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ class ExternalDisplayPolicy {
    @VisibleForTesting
    static final String ENABLE_ON_CONNECT = "persist.sys.display.enable_on_connect.external";

    static boolean isExternalDisplay(@NonNull final LogicalDisplay logicalDisplay) {
    static boolean isExternalDisplayLocked(@NonNull final LogicalDisplay logicalDisplay) {
        return logicalDisplay.getDisplayInfoLocked().type == TYPE_EXTERNAL;
    }

@@ -85,6 +85,9 @@ class ExternalDisplayPolicy {

        @NonNull
        Handler getHandler();

        @NonNull
        ExternalDisplayStatsService getExternalDisplayStatsService();
    }

    @NonNull
@@ -99,6 +102,8 @@ class ExternalDisplayPolicy {
    private final DisplayNotificationManager mDisplayNotificationManager;
    @NonNull
    private final Handler mHandler;
    @NonNull
    private final ExternalDisplayStatsService mExternalDisplayStatsService;
    @ThrottlingStatus
    private volatile int mStatus = THROTTLING_NONE;

@@ -109,6 +114,7 @@ class ExternalDisplayPolicy {
        mFlags = mInjector.getFlags();
        mDisplayNotificationManager = mInjector.getDisplayNotificationManager();
        mHandler = mInjector.getHandler();
        mExternalDisplayStatsService = mInjector.getExternalDisplayStatsService();
    }

    /**
@@ -141,7 +147,7 @@ class ExternalDisplayPolicy {
     */
    void setExternalDisplayEnabledLocked(@NonNull final LogicalDisplay logicalDisplay,
            final boolean enabled) {
        if (!isExternalDisplay(logicalDisplay)) {
        if (!isExternalDisplayLocked(logicalDisplay)) {
            Slog.e(TAG, "setExternalDisplayEnabledLocked called for non external display");
            return;
        }
@@ -170,7 +176,7 @@ class ExternalDisplayPolicy {
     * user to decide how to use this display.
     */
    void handleExternalDisplayConnectedLocked(@NonNull final LogicalDisplay logicalDisplay) {
        if (!isExternalDisplay(logicalDisplay)) {
        if (!isExternalDisplayLocked(logicalDisplay)) {
            Slog.e(TAG, "handleExternalDisplayConnectedLocked called for non-external display");
            return;
        }
@@ -183,6 +189,8 @@ class ExternalDisplayPolicy {
            return;
        }

        mExternalDisplayStatsService.onDisplayConnected(logicalDisplay);

        if ((Build.IS_ENG || Build.IS_USERDEBUG)
                && SystemProperties.getBoolean(ENABLE_ON_CONNECT, false)) {
            Slog.w(TAG, "External display is enabled by default, bypassing user consent.");
@@ -209,9 +217,59 @@ class ExternalDisplayPolicy {
        }
    }

    /**
     * Upon external display become unavailable.
     */
    void handleLogicalDisplayDisconnectedLocked(@NonNull final LogicalDisplay logicalDisplay) {
        // Type of the display here is always UNKNOWN, so we can't verify it is an external display

        if (!mFlags.isConnectedDisplayManagementEnabled()) {
            return;
        }

        mExternalDisplayStatsService.onDisplayDisconnected(logicalDisplay.getDisplayIdLocked());
    }

    /**
     * Upon external display gets added.
     */
    void handleLogicalDisplayAddedLocked(@NonNull final LogicalDisplay logicalDisplay) {
        if (!isExternalDisplayLocked(logicalDisplay)) {
            return;
        }

        if (!mFlags.isConnectedDisplayManagementEnabled()) {
            return;
        }

        mExternalDisplayStatsService.onDisplayAdded(logicalDisplay.getDisplayIdLocked());
    }

    /**
     * Upon presentation started.
     */
    void onPresentation(int displayId, boolean isShown) {
        synchronized (mSyncRoot) {
            var logicalDisplay = mLogicalDisplayMapper.getDisplayLocked(displayId);
            if (logicalDisplay == null || !isExternalDisplayLocked(logicalDisplay)) {
                return;
            }
        }

        if (!mFlags.isConnectedDisplayManagementEnabled()) {
            return;
        }

        if (isShown) {
            mExternalDisplayStatsService.onPresentationWindowAdded(displayId);
        } else {
            mExternalDisplayStatsService.onPresentationWindowRemoved(displayId);
        }
    }

    @GuardedBy("mSyncRoot")
    private void disableExternalDisplayLocked(@NonNull final LogicalDisplay logicalDisplay) {
        if (!isExternalDisplay(logicalDisplay)) {
        if (!isExternalDisplayLocked(logicalDisplay)) {
            return;
        }

@@ -245,6 +303,8 @@ class ExternalDisplayPolicy {

        mLogicalDisplayMapper.setDisplayEnabledLocked(logicalDisplay, /*enabled=*/ false);

        mExternalDisplayStatsService.onDisplayDisabled(logicalDisplay.getDisplayIdLocked());

        if (DEBUG) {
            Slog.d(TAG, "disableExternalDisplayLocked complete"
                                + " displayId=" + logicalDisplay.getDisplayIdLocked());
+662 −0

File added.

Preview size limit exceeded, changes collapsed.

+22 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.Slog;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.ExternalDisplayStatsService;
import com.android.server.display.feature.DisplayManagerFlags;

/**
@@ -45,6 +46,10 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
        /** Get {@link ConnectedDisplayUsbErrorsDetector} or null if not available. */
        @Nullable
        ConnectedDisplayUsbErrorsDetector getUsbErrorsDetector();

        /** Get {@link com.android.server.display.ExternalDisplayStatsService} or null */
        @Nullable
        ExternalDisplayStatsService getExternalDisplayStatsService();
    }

    private static final String TAG = "DisplayNotificationManager";
@@ -59,7 +64,10 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
    private NotificationManager mNotificationManager;
    private ConnectedDisplayUsbErrorsDetector mConnectedDisplayUsbErrorsDetector;

    public DisplayNotificationManager(final DisplayManagerFlags flags, final Context context) {
    private final ExternalDisplayStatsService mExternalDisplayStatsService;

    public DisplayNotificationManager(final DisplayManagerFlags flags, final Context context,
            final ExternalDisplayStatsService statsService) {
        this(flags, context, new Injector() {
            @Nullable
            @Override
@@ -72,6 +80,12 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
            public ConnectedDisplayUsbErrorsDetector getUsbErrorsDetector() {
                return new ConnectedDisplayUsbErrorsDetector(flags, context);
            }

            @Nullable
            @Override
            public ExternalDisplayStatsService getExternalDisplayStatsService() {
                return statsService;
            }
        });
    }

@@ -81,6 +95,7 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
        mConnectedDisplayErrorHandlingEnabled = flags.isConnectedDisplayErrorHandlingEnabled();
        mContext = context;
        mInjector = injector;
        mExternalDisplayStatsService = injector.getExternalDisplayStatsService();
    }

    /**
@@ -111,6 +126,8 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
            return;
        }

        mExternalDisplayStatsService.onDisplayPortLinkTrainingFailure();

        sendErrorNotification(createErrorNotification(
                R.string.connected_display_unavailable_notification_title,
                R.string.connected_display_unavailable_notification_content,
@@ -129,6 +146,8 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
            return;
        }

        mExternalDisplayStatsService.onCableNotCapableDisplayPort();

        sendErrorNotification(createErrorNotification(
                R.string.connected_display_unavailable_notification_title,
                R.string.connected_display_unavailable_notification_content,
@@ -145,6 +164,8 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
            return;
        }

        mExternalDisplayStatsService.onHotplugConnectionError();

        sendErrorNotification(createErrorNotification(
                R.string.connected_display_unavailable_notification_title,
                R.string.connected_display_unavailable_notification_content,
Loading