summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2014-05-20 16:45:45 +0900
committerJungshik Jang <jayjang@google.com>2014-06-02 10:45:18 +0900
commit47927f756a0f694358567cec845b53ab3fc980e9 (patch)
tree725e65ba4f5ee25460dd92245734c60f0d3ed975 /services
parent404d704158d068c9b1f066ec647461f0f9ec22cd (diff)
downloadframeworks_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')
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecController.java95
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java78
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java36
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java43
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.
+ }
+}