diff options
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) { |