diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-05-20 16:45:45 +0900 |
---|---|---|
committer | Jungshik Jang <jayjang@google.com> | 2014-06-02 10:45:18 +0900 |
commit | 47927f756a0f694358567cec845b53ab3fc980e9 (patch) | |
tree | 725e65ba4f5ee25460dd92245734c60f0d3ed975 /services | |
parent | 404d704158d068c9b1f066ec647461f0f9ec22cd (diff) | |
download | frameworks_base-47927f756a0f694358567cec845b53ab3fc980e9.zip frameworks_base-47927f756a0f694358567cec845b53ab3fc980e9.tar.gz frameworks_base-47927f756a0f694358567cec845b53ab3fc980e9.tar.bz2 |
DO NOT MERGE: CEC Initialization per device type
CEC initialization may vary from device type to type. Changed logical address
map to HdmiCecLocalDevice map to handle it. These per-type classes for local
device will be extended also to take care of incoming CEC commands that should
require different action based on device type.
Change-Id: Ia59a464607b14e942fcf83e63aa1d6310ca6a575
Diffstat (limited to 'services')
4 files changed, 199 insertions, 53 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index 662159d..23044dd 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -21,7 +21,6 @@ import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCecMessage; import android.os.Handler; import android.util.SparseArray; -import android.util.SparseIntArray; import libcore.util.EmptyArray; @@ -75,14 +74,12 @@ final class HdmiCecController { // used as key of container. private final SparseArray<HdmiCecDeviceInfo> mDeviceInfos = new SparseArray<HdmiCecDeviceInfo>(); - // Set-like container for all local devices' logical address. - // Key and value are same. - private final SparseIntArray mLocalAddresses = new SparseIntArray(); + + // Stores the local CEC devices in the system. + private final ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); // Private constructor. Use HdmiCecController.create(). private HdmiCecController() { - // TODO: Consider restoring the local device addresses from persistent storage - // to allocate the same addresses again if possible. } /** @@ -96,53 +93,41 @@ final class HdmiCecController { * returns {@code null}. */ static HdmiCecController create(HdmiControlService service) { - HdmiCecController handler = new HdmiCecController(); - long nativePtr = nativeInit(handler); + HdmiCecController controller = new HdmiCecController(); + long nativePtr = nativeInit(controller); if (nativePtr == 0L) { - handler = null; + controller = null; return null; } - handler.init(service, nativePtr); - return handler; + controller.init(service, nativePtr); + return controller; } - /** - * Initialize {@link #mLocalAddresses} by allocating logical addresses for each hosted type. - * - * @param deviceTypes local device types - */ - void initializeLocalDevices(int[] deviceTypes) { - for (int deviceType : deviceTypes) { - int preferred = getPreferredAddress(deviceType); - allocateLogicalAddress(deviceType, preferred, new AllocateLogicalAddressCallback() { - @Override - public void onAllocated(int deviceType, int logicalAddress) { - addLogicalAddress(logicalAddress); - } - }); - } + private void init(HdmiControlService service, long nativePtr) { + mService = service; + mIoHandler = new Handler(service.getServiceLooper()); + mControlHandler = new Handler(service.getServiceLooper()); + mNativePtr = nativePtr; } /** - * Get the preferred address for a given type. + * Perform initialization for each hosted device. * - * @param deviceType logical device type to get the address for - * @return preferred address; {@link HdmiCec#ADDR_UNREGISTERED} if not available. + * @param deviceTypes array of device types */ - private int getPreferredAddress(int deviceType) { - // Uses the data restored from persistent memory at boot up if they are available. - // Otherwise we return UNREGISTERED indicating there is no preferred address. - // Note that for address SPECIFIC_USE(14), HdmiCec.getTypeFromAddress() returns DEVICE_TV, - // meaning that we do not support device type video processor yet. - for (int i = 0; i < mLocalAddresses.size(); ++i) { - int address = mLocalAddresses.keyAt(i); - int type = HdmiCec.getTypeFromAddress(address); - if (type == deviceType) { - return address; + void initializeLocalDevices(int[] deviceTypes) { + for (int type : deviceTypes) { + HdmiCecLocalDevice device = HdmiCecLocalDevice.create(this, type); + if (device == null) { + continue; } + // TODO: Consider restoring the local device addresses from persistent storage + // to allocate the same addresses again if possible. + device.setPreferredAddress(HdmiCec.ADDR_UNREGISTERED); + mLocalDevices.add(device); + device.init(); } - return HdmiCec.ADDR_UNREGISTERED; } /** @@ -310,7 +295,6 @@ final class HdmiCecController { */ int addLogicalAddress(int newLogicalAddress) { if (HdmiCec.isValidAddress(newLogicalAddress)) { - mLocalAddresses.put(newLogicalAddress, newLogicalAddress); return nativeAddLogicalAddress(mNativePtr, newLogicalAddress); } else { return -1; @@ -325,7 +309,9 @@ final class HdmiCecController { void clearLogicalAddress() { // TODO: consider to backup logical address so that new logical address // allocation can use it as preferred address. - mLocalAddresses.clear(); + for (HdmiCecLocalDevice device : mLocalDevices) { + device.clearAddress(); + } nativeClearLogicalAddress(mNativePtr); } @@ -367,18 +353,17 @@ final class HdmiCecController { mControlHandler.post(runnable); } - private void init(HdmiControlService service, long nativePtr) { - mService = service; - mIoHandler = new Handler(service.getServiceLooper()); - mControlHandler = new Handler(service.getServiceLooper()); - mNativePtr = nativePtr; - } - private boolean isAcceptableAddress(int address) { - // Can access command targeting devices available in local device or - // broadcast command. - return address == HdmiCec.ADDR_BROADCAST - || mLocalAddresses.indexOfKey(address) < 0; + // Can access command targeting devices available in local device or broadcast command. + if (address == HdmiCec.ADDR_BROADCAST) { + return true; + } + for (HdmiCecLocalDevice device : mLocalDevices) { + if (device.isAddressOf(address)) { + return true; + } + } + return false; } private void onReceiveCommand(HdmiCecMessage message) { @@ -397,6 +382,10 @@ final class HdmiCecController { sendCommand(cecMessage, null); } + void sendCommand(HdmiCecMessage cecMessage) { + sendCommand(cecMessage, null); + } + void sendCommand(final HdmiCecMessage cecMessage, final HdmiControlService.SendMessageCallback callback) { runOnIoThread(new Runnable() { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java new file mode 100644 index 0000000..789a551 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 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.hdmi; + +import com.android.server.hdmi.HdmiCecController.AllocateLogicalAddressCallback; + +import android.hardware.hdmi.HdmiCec; + +/** + * Class that models a logical CEC device hosted in this system. Handles initialization, + * CEC commands that call for actions customized per device type. + */ +abstract class HdmiCecLocalDevice { + + protected final HdmiCecController mController; + protected final int mDeviceType; + protected int mAddress; + protected int mPreferredAddress; + + protected HdmiCecLocalDevice(HdmiCecController controller, int deviceType) { + mController = controller; + mDeviceType = deviceType; + mAddress = HdmiCec.ADDR_UNREGISTERED; + } + + // Factory method that returns HdmiCecLocalDevice of corresponding type. + static HdmiCecLocalDevice create(HdmiCecController controller, int deviceType) { + switch (deviceType) { + case HdmiCec.DEVICE_TV: + return new HdmiCecLocalDeviceTv(controller); + case HdmiCec.DEVICE_PLAYBACK: + return new HdmiCecLocalDevicePlayback(controller); + default: + return null; + } + } + + abstract void init(); + + protected void allocateAddress(int type) { + mController.allocateLogicalAddress(type, mPreferredAddress, + new AllocateLogicalAddressCallback() { + @Override + public void onAllocated(int deviceType, int logicalAddress) { + mAddress = mPreferredAddress = logicalAddress; + mController.addLogicalAddress(logicalAddress); + } + }); + } + + // Returns true if the logical address is same as the argument. + boolean isAddressOf(int addr) { + return addr == mAddress; + } + + // Resets the logical address to unregistered(15), meaning the logical device is invalid. + void clearAddress() { + mAddress = HdmiCec.ADDR_UNREGISTERED; + } + + void setPreferredAddress(int addr) { + mPreferredAddress = addr; + } +} diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java new file mode 100644 index 0000000..a953467 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2014 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.hdmi; + +import android.hardware.hdmi.HdmiCec; + +/** + * Represent a logical device of type Playback residing in Android system. + */ +final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { + + HdmiCecLocalDevicePlayback(HdmiCecController controller) { + super(controller, HdmiCec.DEVICE_PLAYBACK); + } + + @Override + void init() { + allocateAddress(mDeviceType); + 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 new file mode 100644 index 0000000..01ea685 --- /dev/null +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2014 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.hdmi; + +import android.hardware.hdmi.HdmiCec; + +/** + * Represent a logical device of type TV residing in Android system. + */ +final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { + + HdmiCecLocalDeviceTv(HdmiCecController controller) { + super(controller, HdmiCec.DEVICE_TV); + } + + @Override + void init() { + allocateAddress(mDeviceType); + + // TODO: vendor-specific initialization here. + + mController.sendCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand( + mAddress, mController.getPhysicalAddress(), mDeviceType)); + mController.sendCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand( + mAddress, mController.getVendorId())); + + // TODO: Start routing control action, device discovery action. + } +} |