From 6f87b4e6b6db76cb32d449ad1fdf1946ff4e96f7 Mon Sep 17 00:00:00 2001 From: Jinsuk Kim Date: Fri, 10 Oct 2014 14:40:29 +0900 Subject: [PATCH] CEC: Queue actions for starting later when not ready Requests coming in while the service is still being brought up were discarded. Changed to queue them so that they can be started after the initialization is completed. Bug: 17933899 Change-Id: Ic9d9cd2094b830c80dec54dd5ef6a18159a74dc7 --- .../android/server/hdmi/HdmiCecFeatureAction.java | 9 +++++++-- .../android/server/hdmi/HdmiCecLocalDevice.java | 15 +++++++++++++-- .../server/hdmi/HdmiCecLocalDevicePlayback.java | 7 +++++++ .../android/server/hdmi/HdmiCecLocalDeviceTv.java | 1 + .../android/server/hdmi/HdmiControlService.java | 9 +++++++-- 5 files changed, 35 insertions(+), 6 deletions(-) diff --git a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java index c47e0e96e70cc..d26be575f2143 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecFeatureAction.java @@ -73,8 +73,9 @@ abstract class HdmiCecFeatureAction { } /** - * Called right after the action is created. Initialization or first step to take - * for the action can be done in this method. + * Called after the action is created. Initialization or first step to take + * for the action can be done in this method. Shall update {@code mState} to + * indicate that the action has started. * * @return true if the operation is successful; otherwise false. */ @@ -161,6 +162,10 @@ abstract class HdmiCecFeatureAction { mActionTimer.sendTimerMessage(state, delayMillis); } + boolean started() { + return mState != STATE_NONE; + } + protected final void sendCommand(HdmiCecMessage cmd) { mService.sendCecCommand(cmd); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index 2ba6ceeb3f73c..836a46334e70b 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -616,14 +616,25 @@ abstract class HdmiCecLocalDevice { @ServiceThreadOnly void addAndStartAction(final HdmiCecFeatureAction action) { assertRunOnServiceThread(); + mActions.add(action); if (mService.isPowerStandbyOrTransient()) { - Slog.w(TAG, "Skip the action during Standby: " + action); + Slog.i(TAG, "Not ready to start action. Queued for deferred start:" + action); return; } - mActions.add(action); action.start(); } + @ServiceThreadOnly + void startQueuedActions() { + assertRunOnServiceThread(); + for (HdmiCecFeatureAction action : mActions) { + if (!action.started()) { + Slog.i(TAG, "Starting queued action:" + action); + action.start(); + } + } + } + // See if we have an action of a given type in progress. @ServiceThreadOnly boolean hasAction(final Class clazz) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index b406ebdd75737..da508e872b492 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -38,6 +38,12 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { super(service, HdmiDeviceInfo.DEVICE_PLAYBACK); } + @Override + void init() { + super.init(); + mIsActiveSource = false; + } + @Override @ServiceThreadOnly protected void onAddressAllocated(int logicalAddress, int reason) { @@ -46,6 +52,7 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { mAddress, mService.getPhysicalAddress(), mDeviceType)); mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand( mAddress, mService.getVendorId())); + startQueuedActions(); } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index f6069bb7654b3..1a5678b629612 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -142,6 +142,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC && reason != HdmiControlService.INITIATED_BY_BOOT_UP); launchDeviceDiscovery(); + startQueuedActions(); } @Override diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index d73f8fbc5db60..b653e090369b6 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -415,12 +415,17 @@ public final class HdmiControlService extends SystemService { assertRunOnServiceThread(); // A container for [Device type, Local device info]. ArrayList localDevices = new ArrayList<>(); - clearLocalDevices(); for (int type : mLocalDevices) { - final HdmiCecLocalDevice localDevice = HdmiCecLocalDevice.create(this, type); + HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(type); + if (localDevice == null) { + localDevice = HdmiCecLocalDevice.create(this, type); + } localDevice.init(); localDevices.add(localDevice); } + // It's now safe to flush existing local devices from mCecController since they were + // already moved to 'localDevices'. + clearLocalDevices(); allocateLogicalAddress(localDevices, initiatedBy); }