diff options
author | Jungshik Jang <jayjang@google.com> | 2014-05-29 21:52:28 +0900 |
---|---|---|
committer | Jungshik Jang <jayjang@google.com> | 2014-06-02 11:07:25 +0900 |
commit | 3ef57d99b3b1b751097d58c6c1b98db123d5ccc5 (patch) | |
tree | 8d18b9d78b74fc9b4990b3e4b3307c851f5fa4bb /services | |
parent | af9d45e88b173a30cd20db854731e0e5eb207afa (diff) | |
download | frameworks_base-3ef57d99b3b1b751097d58c6c1b98db123d5ccc5.zip frameworks_base-3ef57d99b3b1b751097d58c6c1b98db123d5ccc5.tar.gz frameworks_base-3ef57d99b3b1b751097d58c6c1b98db123d5ccc5.tar.bz2 |
DO NOT MERGE: Start Device Discovery after logical address allocation.
Usually TV initiates Device Discovery sequence after logical address
allocation of local devices. For that added new callback interface
to AddressAllocationCallback to HdmiCecDevice.
Along with this, add onAddressAllocated to HdmiLocalDevice so that
start sending local device information once logical allocation is done.
Change-Id: I4cdc5dd7770674a17a0f23c383a6c1ca221e3104
Diffstat (limited to 'services')
6 files changed, 96 insertions, 16 deletions
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java index d46cc7b..579f89f 100644 --- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java +++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java @@ -115,12 +115,12 @@ final class DeviceDiscoveryAction extends FeatureAction { @Override public void onPollingFinished(List<Integer> ackedAddress) { if (ackedAddress.isEmpty()) { - Slog.i(TAG, "No device is detected."); + Slog.v(TAG, "No device is detected."); finish(); return; } - Slog.i(TAG, "Device detected: " + ackedAddress); + Slog.v(TAG, "Device detected: " + ackedAddress); allocateDevices(ackedAddress); startPhysicalAddressStage(); } @@ -136,6 +136,7 @@ final class DeviceDiscoveryAction extends FeatureAction { } private void startPhysicalAddressStage() { + Slog.v(TAG, "Start [Physical Address Stage]:" + mDevices.size()); mProcessedDeviceCount = 0; mState = STATE_WAITING_FOR_PHYSICAL_ADDRESS; @@ -158,6 +159,7 @@ final class DeviceDiscoveryAction extends FeatureAction { } private void startOsdNameStage() { + Slog.v(TAG, "Start [Osd Name Stage]:" + mDevices.size()); mProcessedDeviceCount = 0; mState = STATE_WAITING_FOR_OSD_NAME; @@ -176,6 +178,8 @@ final class DeviceDiscoveryAction extends FeatureAction { } private void startVendorIdStage() { + Slog.v(TAG, "Start [Vendor Id Stage]:" + mDevices.size()); + mProcessedDeviceCount = 0; mState = STATE_WAITING_FOR_VENDOR_ID; @@ -301,11 +305,14 @@ final class DeviceDiscoveryAction extends FeatureAction { } private void wrapUpAndFinish() { + Slog.v(TAG, "---------Wrap up Device Discovery:[" + mDevices.size() + "]---------"); ArrayList<HdmiCecDeviceInfo> result = new ArrayList<>(); for (DeviceInfo info : mDevices) { HdmiCecDeviceInfo cecDeviceInfo = info.toHdmiCecDeviceInfo(); + Slog.v(TAG, " DeviceInfo: " + cecDeviceInfo); result.add(cecDeviceInfo); } + Slog.v(TAG, "--------------------------------------------"); mCallback.onDeviceDiscoveryDone(result); finish(); } @@ -355,6 +362,7 @@ final class DeviceDiscoveryAction extends FeatureAction { return; } + Slog.v(TAG, "Timeout[State=" + mState + ", Processed=" + mProcessedDeviceCount); removeDevice(mProcessedDeviceCount); checkAndProceedStage(); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index e0a01f0..d0b716d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -121,10 +121,11 @@ final class HdmiCecController { * * @param deviceTypes array of device types */ - void initializeLocalDevices(int[] deviceTypes) { + void initializeLocalDevices(int[] deviceTypes, + HdmiCecLocalDevice.AddressAllocationCallback callback) { assertRunOnServiceThread(); for (int type : deviceTypes) { - HdmiCecLocalDevice device = HdmiCecLocalDevice.create(this, type); + HdmiCecLocalDevice device = HdmiCecLocalDevice.create(this, type, callback); if (device == null) { continue; } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java index e65e5fa..aac2a15 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -29,23 +29,41 @@ abstract class HdmiCecLocalDevice { protected final HdmiCecController mController; protected final int mDeviceType; + protected final AddressAllocationCallback mAllocationCallback; protected int mAddress; protected int mPreferredAddress; protected HdmiCecDeviceInfo mDeviceInfo; - protected HdmiCecLocalDevice(HdmiCecController controller, int deviceType) { + /** + * Callback interface to notify newly allocated logical address of the given + * local device. + */ + interface AddressAllocationCallback { + /** + * Called when a logical address of the given device is allocated. + * + * @param deviceType original device type + * @param logicalAddress newly allocated logical address + */ + void onAddressAllocated(int deviceType, int logicalAddress); + } + + protected HdmiCecLocalDevice(HdmiCecController controller, int deviceType, + AddressAllocationCallback callback) { mController = controller; mDeviceType = deviceType; + mAllocationCallback = callback; mAddress = HdmiCec.ADDR_UNREGISTERED; } // Factory method that returns HdmiCecLocalDevice of corresponding type. - static HdmiCecLocalDevice create(HdmiCecController controller, int deviceType) { + static HdmiCecLocalDevice create(HdmiCecController controller, int deviceType, + AddressAllocationCallback callback) { switch (deviceType) { case HdmiCec.DEVICE_TV: - return new HdmiCecLocalDeviceTv(controller); + return new HdmiCecLocalDeviceTv(controller, callback); case HdmiCec.DEVICE_PLAYBACK: - return new HdmiCecLocalDevicePlayback(controller); + return new HdmiCecLocalDevicePlayback(controller, callback); default: return null; } @@ -53,6 +71,12 @@ abstract class HdmiCecLocalDevice { abstract void init(); + /** + * Called when a logical address of the local device is allocated. + * Note that internal variables are updated before it's called. + */ + protected abstract void onAddressAllocated(int logicalAddress); + protected void allocateAddress(int type) { mController.allocateLogicalAddress(type, mPreferredAddress, new AllocateLogicalAddressCallback() { @@ -66,6 +90,10 @@ abstract class HdmiCecLocalDevice { mController.addDeviceInfo(deviceInfo); mController.addLogicalAddress(logicalAddress); + onAddressAllocated(logicalAddress); + if (mAllocationCallback != null) { + mAllocationCallback.onAddressAllocated(deviceType, logicalAddress); + } } }); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index a953467..3347725 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -23,13 +23,17 @@ import android.hardware.hdmi.HdmiCec; */ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { - HdmiCecLocalDevicePlayback(HdmiCecController controller) { - super(controller, HdmiCec.DEVICE_PLAYBACK); + HdmiCecLocalDevicePlayback(HdmiCecController controller, AddressAllocationCallback callback) { + super(controller, HdmiCec.DEVICE_PLAYBACK, callback); } @Override void init() { allocateAddress(mDeviceType); + } + + @Override + protected void onAddressAllocated(int logicalAddress) { mController.sendCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( mAddress, mController.getPhysicalAddress(), mDeviceType)); } diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 01ea685..93761ab 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -23,14 +23,17 @@ import android.hardware.hdmi.HdmiCec; */ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { - HdmiCecLocalDeviceTv(HdmiCecController controller) { - super(controller, HdmiCec.DEVICE_TV); + HdmiCecLocalDeviceTv(HdmiCecController controller, AddressAllocationCallback callback) { + super(controller, HdmiCec.DEVICE_TV, callback); } @Override void init() { allocateAddress(mDeviceType); + } + @Override + protected void onAddressAllocated(int logicalAddress) { // TODO: vendor-specific initialization here. mController.sendCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 83225f0..d775733 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -30,10 +30,12 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; import android.util.Slog; +import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.server.SystemService; import com.android.server.hdmi.DeviceDiscoveryAction.DeviceDiscoveryCallback; +import com.android.server.hdmi.HdmiCecLocalDevice.AddressAllocationCallback; import java.util.ArrayList; import java.util.Iterator; @@ -130,7 +132,22 @@ public final class HdmiControlService extends SystemService { mIoThread.start(); mCecController = HdmiCecController.create(this); if (mCecController != null) { - mCecController.initializeLocalDevices(mLocalDevices); + mCecController.initializeLocalDevices(mLocalDevices, new AddressAllocationCallback() { + private final SparseIntArray mAllocated = new SparseIntArray(); + + @Override + public void onAddressAllocated(int deviceType, int logicalAddress) { + mAllocated.append(deviceType, logicalAddress); + // TODO: get HdmiLCecLocalDevice and call onAddressAllocated here. + + // Once all logical allocation is done, launch device discovery + // action if one of local device is TV. + int tvAddress = mAllocated.get(HdmiCec.DEVICE_TV, -1); + if (mLocalDevices.length == mAllocated.size() && tvAddress != -1) { + launchDeviceDiscovery(tvAddress); + } + } + }); } else { Slog.i(TAG, "Device does not support HDMI-CEC."); } @@ -286,6 +303,9 @@ public final class HdmiControlService extends SystemService { case HdmiCec.MESSAGE_TERMINATE_ARC: handleTerminateArc(message); return true; + case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS: + handleReportPhysicalAddress(message); + return true; // TODO: Add remaining system information query such as // <Give Device Power Status> and <Request Active Source> handler. default: @@ -296,7 +316,7 @@ public final class HdmiControlService extends SystemService { /** * Called when a new hotplug event is issued. * - * @param port hdmi port number where hot plug event issued. + * @param portNo hdmi port number where hot plug event issued. * @param connected whether to be plugged in or not */ void onHotplug(int portNo, boolean connected) { @@ -314,6 +334,22 @@ public final class HdmiControlService extends SystemService { mCecController.pollDevices(callback, retryCount); } + private void handleReportPhysicalAddress(HdmiCecMessage message) { + // At first, try to consume it. + if (dispatchMessageToAction(message)) { + return; + } + + // Ignore if [Device Discovery Action] is on going ignore message. + if (hasAction(DeviceDiscoveryAction.class)) { + Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> " + + "because Device Discovery Action is on-going:" + message); + return; + } + + // TODO: start new device action. + } + private void handleInitiateArc(HdmiCecMessage message){ // In case where <Initiate Arc> is started by <Request ARC Initiation> // need to clean up RequestArcInitiationAction. @@ -427,12 +463,12 @@ public final class HdmiControlService extends SystemService { // Launch device discovery sequence. // It starts with clearing the existing device info list. // Note that it assumes that logical address of all local devices is already allocated. - void launchDeviceDiscovery() { + private void launchDeviceDiscovery(int sourceAddress) { // At first, clear all existing device infos. mCecController.clearDeviceInfoList(); // TODO: check whether TV is one of local devices. - DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, HdmiCec.ADDR_TV, + DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, sourceAddress, new DeviceDiscoveryCallback() { @Override public void onDeviceDiscoveryDone(List<HdmiCecDeviceInfo> deviceInfos) { |