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

Commit bb4cfd02 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "HDMI: Change on active source lost behavior [1/2]" into main

parents 8bfd5373 fd5c17be
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -138,6 +138,16 @@ public final class HdmiControlManager {
     */
    public static final String EXTRA_LOCALE = "android.hardware.hdmi.extra.LOCALE";

    /**
     * Broadcast Action: Active Source status was recovered by the device.
     * <p>Send when device becomes the current active source such that the activity
     * HdmiCecActiveSourceLostActivity can be finished and cleared from the screen.
     * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI =
            "android.hardware.hdmi.action.ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI";
    /**
     * Volume value for mute state.
     */
+5 −0
Original line number Diff line number Diff line
@@ -3351,6 +3351,11 @@
        com.android.systemui/com.android.systemui.tv.hdmi.HdmiCecSetMenuLanguageActivity
    </string>

    <!-- Component name of the activity used to inform user that their device lost Active Source
      status and will go to standby if there is no interaction. -->
    <string name="config_hdmiCecActiveSourceLostActivity"
    >com.android.systemui/com.android.systemui.tv.hdmi.HdmiCecActiveSourceLostActivity</string>

    <!-- Name of the dialog that is used to request the user's consent for a Platform VPN -->
    <string name="config_platformVpnConfirmDialogComponent" translatable="false"
            >com.android.vpndialogs/com.android.vpndialogs.PlatformVpnConfirmDialog</string>
+1 −0
Original line number Diff line number Diff line
@@ -390,6 +390,7 @@
  <java-symbol type="string" name="config_sensorUseStartedActivity_hwToggle" />
  <java-symbol type="string" name="config_sensorStateChangedActivity" />
  <java-symbol type="string" name="config_hdmiCecSetMenuLanguageActivity" />
  <java-symbol type="string" name="config_hdmiCecActiveSourceLostActivity" />
  <java-symbol type="integer" name="config_minNumVisibleRecentTasks_lowRam" />
  <java-symbol type="integer" name="config_maxNumVisibleRecentTasks_lowRam" />
  <java-symbol type="integer" name="config_minNumVisibleRecentTasks" />
+79 −1
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.os.Binder;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.sysprop.HdmiProperties;
import android.util.Slog;

@@ -53,6 +54,16 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
    @VisibleForTesting
    static final long STANDBY_AFTER_HOTPLUG_OUT_DELAY_MS = 30_000;

    // How long to wait on active source lost before possibly going to Standby.
    @VisibleForTesting
    static final long STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS = 30_000;

    // How long to wait after losing active source, before launching the pop-up that allows the user
    // to keep the device as the current active source.
    // We do this to prevent an unnecessary pop-up from being displayed when we lose and regain
    // active source within this timeout.
    static final long POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS = 5_000;

    // Used to keep the device awake while it is the active source. For devices that
    // cannot wake up via CEC commands, this address the inconvenience of having to
    // turn them on. True by default, and can be disabled (i.e. device can go to sleep
@@ -64,6 +75,14 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
    // Handler for queueing a delayed Standby runnable after hotplug out.
    private Handler mDelayedStandbyHandler;

    // Handler for queueing a delayed Standby runnable after active source lost and after the pop-up
    // on active source lost was displayed.
    Handler mDelayedStandbyOnActiveSourceLostHandler;

    // Handler for queueing a delayed runnable that triggers a pop-up notification on active source
    // lost.
    private Handler mDelayedPopupOnActiveSourceLostHandler;

    // Determines what action should be taken upon receiving Routing Control messages.
    @VisibleForTesting
    protected HdmiProperties.playback_device_action_on_routing_control_values
@@ -75,6 +94,8 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
        super(service, HdmiDeviceInfo.DEVICE_PLAYBACK);

        mDelayedStandbyHandler = new Handler(service.getServiceLooper());
        mDelayedStandbyOnActiveSourceLostHandler = new Handler(service.getServiceLooper());
        mDelayedPopupOnActiveSourceLostHandler = new Handler(service.getServiceLooper());
        mStandbyHandler = new HdmiCecStandbyModeHandler(service, this);
    }

@@ -239,6 +260,28 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
        }
    }

    private class DelayedStandbyOnActiveSourceLostRunnable implements Runnable {
        @Override
        public void run() {
            if (mService.getPowerManagerInternal().wasDeviceIdleFor(
                    STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS)) {
                mService.standby();
            } else {
                mService.setAndBroadcastActiveSource(mService.getPhysicalAddress(),
                        getDeviceInfo().getDeviceType(), Constants.ADDR_TV,
                        "DelayedActiveSourceLostStandbyRunnable");
            }
        }
    }

    @ServiceThreadOnly
    void dismissUiOnActiveSourceStatusRecovered() {
        assertRunOnServiceThread();
        Intent intent = new Intent(HdmiControlManager.ACTION_ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI);
        mService.getContext().sendBroadcastAsUser(intent, UserHandle.ALL,
                HdmiControlService.PERMISSION);
    }

    @Override
    @ServiceThreadOnly
    protected void onStandby(boolean initiatedByCec, int standbyAction,
@@ -387,13 +430,47 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
        switch (mService.getHdmiCecConfig().getStringValue(
                    HdmiControlManager.CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST)) {
            case HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW:
                mService.standby();
                mDelayedPopupOnActiveSourceLostHandler.removeCallbacksAndMessages(null);
                mDelayedPopupOnActiveSourceLostHandler.postDelayed(
                        new Runnable() {
                            @Override
                            public void run() {
                                if (!isActiveSource()) {
                                    startHdmiCecActiveSourceLostActivity();
                                    mDelayedStandbyOnActiveSourceLostHandler
                                            .removeCallbacksAndMessages(null);
                                    mDelayedStandbyOnActiveSourceLostHandler.postDelayed(
                                            new DelayedStandbyOnActiveSourceLostRunnable(),
                                            STANDBY_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
                                }
                            }
                        }, POPUP_AFTER_ACTIVE_SOURCE_LOST_DELAY_MS);
                return;
            case HdmiControlManager.POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE:
                return;
        }
    }

    @VisibleForTesting
    @ServiceThreadOnly
    void startHdmiCecActiveSourceLostActivity() {
        final long identity = Binder.clearCallingIdentity();
        try {
            Context context = mService.getContext();
            Intent intent = new Intent();
            intent.setComponent(
                    ComponentName.unflattenFromString(context.getResources().getString(
                            com.android.internal.R.string.config_hdmiCecActiveSourceLostActivity
                    )));
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivityAsUser(intent, context.getUser());
        } catch (ActivityNotFoundException e) {
            Slog.e(TAG, "Unable to start HdmiCecActiveSourceLostActivity");
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @ServiceThreadOnly
    @Constants.HandleMessageResult
    protected int handleUserControlPressed(HdmiCecMessage message) {
@@ -557,6 +634,7 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
            setActiveSource(physicalAddress,
                    "HdmiCecLocalDevicePlayback#handleRoutingChangeAndInformation()");
        }
        dismissUiOnActiveSourceStatusRecovered();
        switch (mPlaybackDeviceActionOnRoutingControl) {
            case WAKE_UP_AND_SEND_ACTIVE_SOURCE:
                setAndBroadcastActiveSource(message, physicalAddress,
+2 −0
Original line number Diff line number Diff line
@@ -4205,10 +4205,12 @@ public class HdmiControlService extends SystemService {
        // playback will claim active source. Otherwise audio system will.
        if (deviceType == HdmiDeviceInfo.DEVICE_PLAYBACK) {
            HdmiCecLocalDevicePlayback playback = playback();
            playback.dismissUiOnActiveSourceStatusRecovered();
            playback.setActiveSource(playback.getDeviceInfo().getLogicalAddress(), physicalAddress,
                    caller);
            playback.wakeUpIfActiveSource();
            playback.maySendActiveSource(source);
            playback.mDelayedStandbyOnActiveSourceLostHandler.removeCallbacksAndMessages(null);
        }

        if (deviceType == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
Loading