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

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

Merge "Revert "Connected display usb errors notification"" into main

parents cef77d04 db16cfd0
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -6298,11 +6298,6 @@ ul.</string>
    <!-- Content of connected display unavailable notification. [CHAR LIMIT=NONE] -->
    <string name="connected_display_unavailable_notification_content">Use a different cable and try again</string>

    <!-- Title of cable don't support displays notifications. [CHAR LIMIT=NONE] -->
    <string name="connected_display_cable_dont_support_displays_notification_title">Cable may not support displays</string>
    <!-- Content of cable don't support displays notification. [CHAR LIMIT=NONE] -->
    <string name="connected_display_cable_dont_support_displays_notification_content">Your USB-C cable may not connect to displays properly</string>

    <!-- Name of concurrent display notifications. [CHAR LIMIT=NONE] -->
    <string name="concurrent_display_notification_name">Dual screen</string>
    <!-- Title of concurrent display active notification. [CHAR LIMIT=NONE] -->
+0 −2
Original line number Diff line number Diff line
@@ -5070,8 +5070,6 @@
  <java-symbol type="array" name="device_state_notification_power_save_contents"/>
  <java-symbol type="string" name="connected_display_unavailable_notification_title"/>
  <java-symbol type="string" name="connected_display_unavailable_notification_content"/>
  <java-symbol type="string" name="connected_display_cable_dont_support_displays_notification_title"/>
  <java-symbol type="string" name="connected_display_cable_dont_support_displays_notification_content"/>
  <java-symbol type="string" name="concurrent_display_notification_name"/>
  <java-symbol type="string" name="concurrent_display_notification_active_title"/>
  <java-symbol type="string" name="concurrent_display_notification_active_content"/>
+1 −8
Original line number Diff line number Diff line
@@ -30,8 +30,7 @@ import java.util.Arrays;

class DisplayManagerShellCommand extends ShellCommand {
    private static final String TAG = "DisplayManagerShellCommand";
    private static final String NOTIFICATION_TYPES =
            "on-hotplug-error, on-link-training-failure, on-cable-dp-incapable";
    private static final String NOTIFICATION_TYPES = "on-hotplug-error";

    private final DisplayManagerService mService;
    private final DisplayManagerFlags mFlags;
@@ -194,12 +193,6 @@ class DisplayManagerShellCommand extends ShellCommand {
            case "on-hotplug-error":
                mService.getDisplayNotificationManager().onHotplugConnectionError();
                break;
            case "on-link-training-failure":
                mService.getDisplayNotificationManager().onDisplayPortLinkTrainingFailure();
                break;
            case "on-cable-dp-incapable":
                mService.getDisplayNotificationManager().onCableNotCapableDisplayPort();
                break;
            default:
                getErrPrintWriter().println(
                        "Error: unexpected notification type=" + notificationType + ", use one of: "
+0 −132
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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.server.display.notifications;

import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_CAPABLE_DISABLED;
import static android.hardware.usb.DisplayPortAltModeInfo.DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE;
import static android.hardware.usb.DisplayPortAltModeInfo.LINK_TRAINING_STATUS_FAILURE;

import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.content.Context;
import android.hardware.usb.DisplayPortAltModeInfo;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbManager.DisplayPortAltModeInfoListener;
import android.util.Slog;

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

/**
 * Detects usb issues related to an external display connected.
 */
public class ConnectedDisplayUsbErrorsDetector implements DisplayPortAltModeInfoListener {
    private static final String TAG = "ConnectedDisplayUsbErrorsDetector";

    /**
     * Dependency injection for {@link ConnectedDisplayUsbErrorsDetector}.
     */
    public interface Injector {

        /**
         * @return {@link UsbManager} service.
         */
        UsbManager getUsbManager();
    }

    /**
     * USB errors listener
     */
    public interface Listener {

        /**
         * Link training failure callback.
         */
        void onDisplayPortLinkTrainingFailure();

        /**
         * DisplayPort capable device plugged-in, but cable is not supporting DisplayPort.
         */
        void onCableNotCapableDisplayPort();
    }

    private Listener mListener;
    private final Injector mInjector;
    private final Context mContext;
    private final boolean mIsConnectedDisplayErrorHandlingEnabled;

    ConnectedDisplayUsbErrorsDetector(@NonNull final DisplayManagerFlags flags,
            @NonNull final Context context) {
        this(flags, context, () -> context.getSystemService(UsbManager.class));
    }

    @VisibleForTesting
    ConnectedDisplayUsbErrorsDetector(@NonNull final DisplayManagerFlags flags,
            @NonNull final Context context, @NonNull final Injector injector) {
        mContext = context;
        mInjector = injector;
        mIsConnectedDisplayErrorHandlingEnabled =
                flags.isConnectedDisplayErrorHandlingEnabled();
    }

    /** Register listener for usb error events. */
    @SuppressLint("AndroidFrameworkRequiresPermission")
    void registerListener(final Listener listener) {
        if (!mIsConnectedDisplayErrorHandlingEnabled) {
            return;
        }

        final var usbManager = mInjector.getUsbManager();
        if (usbManager == null) {
            Slog.e(TAG, "UsbManager is null");
            return;
        }

        mListener = listener;

        try {
            usbManager.registerDisplayPortAltModeInfoListener(mContext.getMainExecutor(), this);
        } catch (IllegalStateException e) {
            Slog.e(TAG, "Failed to register listener", e);
        }
    }

    /**
     * Callback upon changes in {@link DisplayPortAltModeInfo}.
     * @param portId    String describing the {@link android.hardware.usb.UsbPort} that was changed.
     * @param info      New {@link DisplayPortAltModeInfo} for the corresponding portId.
     */
    @Override
    public void onDisplayPortAltModeInfoChanged(@NonNull String portId,
            @NonNull DisplayPortAltModeInfo info) {
        if (mListener == null) {
            return;
        }

        if (DISPLAYPORT_ALT_MODE_STATUS_CAPABLE_DISABLED == info.getPartnerSinkStatus()
                && DISPLAYPORT_ALT_MODE_STATUS_NOT_CAPABLE == info.getCableStatus()
        ) {
            mListener.onCableNotCapableDisplayPort();
            return;
        }

        if (LINK_TRAINING_STATUS_FAILURE == info.getLinkTrainingStatus()) {
            mListener.onDisplayPortLinkTrainingFailure();
            return;
        }
    }
}
+2 −57
Original line number Diff line number Diff line
@@ -34,16 +34,12 @@ import com.android.server.display.feature.DisplayManagerFlags;
/**
 * Manages notifications for {@link com.android.server.display.DisplayManagerService}.
 */
public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDetector.Listener {
public class DisplayNotificationManager {
    /** Dependency injection interface for {@link DisplayNotificationManager} */
    public interface Injector {
        /** Get {@link NotificationManager} service or null if not available. */
        @Nullable
        NotificationManager getNotificationManager();

        /** Get {@link ConnectedDisplayUsbErrorsDetector} or null if not available. */
        @Nullable
        ConnectedDisplayUsbErrorsDetector getUsbErrorsDetector();
    }

    private static final String TAG = "DisplayNotificationManager";
@@ -56,22 +52,9 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
    private final Context mContext;
    private final boolean mConnectedDisplayErrorHandlingEnabled;
    private NotificationManager mNotificationManager;
    private ConnectedDisplayUsbErrorsDetector mConnectedDisplayUsbErrorsDetector;

    public DisplayNotificationManager(final DisplayManagerFlags flags, final Context context) {
        this(flags, context, new Injector() {
            @Nullable
            @Override
            public NotificationManager getNotificationManager() {
                return context.getSystemService(NotificationManager.class);
            }

            @Nullable
            @Override
            public ConnectedDisplayUsbErrorsDetector getUsbErrorsDetector() {
                return new ConnectedDisplayUsbErrorsDetector(flags, context);
            }
        });
        this(flags, context, () -> context.getSystemService(NotificationManager.class));
    }

    @VisibleForTesting
@@ -92,44 +75,6 @@ public class DisplayNotificationManager implements ConnectedDisplayUsbErrorsDete
            Slog.e(TAG, "onBootCompleted: NotificationManager is null");
            return;
        }

        mConnectedDisplayUsbErrorsDetector = mInjector.getUsbErrorsDetector();
        if (mConnectedDisplayUsbErrorsDetector != null) {
            mConnectedDisplayUsbErrorsDetector.registerListener(this);
        }
    }

    /**
     * Display error notification upon DisplayPort link training failure.
     */
    @Override
    public void onDisplayPortLinkTrainingFailure() {
        if (!mConnectedDisplayErrorHandlingEnabled) {
            Slog.d(TAG, "onDisplayPortLinkTrainingFailure:"
                                + " mConnectedDisplayErrorHandlingEnabled is false");
            return;
        }

        sendErrorNotification(createErrorNotification(
                R.string.connected_display_unavailable_notification_title,
                R.string.connected_display_unavailable_notification_content));
    }

    /**
     * Display error notification upon cable not capable of DisplayPort connected to a device
     * capable of DisplayPort.
     */
    @Override
    public void onCableNotCapableDisplayPort() {
        if (!mConnectedDisplayErrorHandlingEnabled) {
            Slog.d(TAG, "onCableNotCapableDisplayPort:"
                                + " mConnectedDisplayErrorHandlingEnabled is false");
            return;
        }

        sendErrorNotification(createErrorNotification(
                R.string.connected_display_cable_dont_support_displays_notification_title,
                R.string.connected_display_cable_dont_support_displays_notification_content));
    }

    /**
Loading