Loading services/core/java/com/android/server/hdmi/HdmiCecController.java +18 −7 Original line number Diff line number Diff line Loading @@ -80,8 +80,8 @@ final class HdmiCecController { // A logical address of device is used as key of container. private final SparseArray<HdmiCecDeviceInfo> mDeviceInfos = new SparseArray<>(); // Stores the local CEC devices in the system. private final ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); // Stores the local CEC devices in the system. Device type is used for key. private final SparseArray<HdmiCecLocalDevice> mLocalDevices = new SparseArray<>(); // Private constructor. Use HdmiCecController.create(). private HdmiCecController() { Loading Loading @@ -131,7 +131,7 @@ final class HdmiCecController { // 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); mLocalDevices.put(type, device); device.init(); } } Loading Loading @@ -289,6 +289,17 @@ final class HdmiCecController { return mDeviceInfos.get(logicalAddress); } /** * Return the locally hosted logical device of a given type. * * @param deviceType logical device type * @return {@link HdmiCecLocalDevice} instance if the instance of the type is available; * otherwise null. */ HdmiCecLocalDevice getLocalDevice(int deviceType) { return mLocalDevices.get(deviceType); } /** * Add a new logical address to the device. Device's HW should be notified * when a new logical address is assigned to a device, so that it can accept Loading Loading @@ -317,8 +328,8 @@ final class HdmiCecController { assertRunOnServiceThread(); // TODO: consider to backup logical address so that new logical address // allocation can use it as preferred address. for (HdmiCecLocalDevice device : mLocalDevices) { device.clearAddress(); for (int i = 0; i < mLocalDevices.size(); ++i) { mLocalDevices.valueAt(i).clearAddress(); } nativeClearLogicalAddress(mNativePtr); } Loading Loading @@ -379,8 +390,8 @@ final class HdmiCecController { } private boolean isAllocatedLocalDeviceAddress(int address) { for (HdmiCecLocalDevice device : mLocalDevices) { if (device.isAddressOf(address)) { for (int i = 0; i < mLocalDevices.size(); ++i) { if (mLocalDevices.valueAt(i).isAddressOf(address)) { return true; } } Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +87 −10 Original line number Diff line number Diff line Loading @@ -178,6 +178,16 @@ public final class HdmiControlService extends SystemService { }); } // See if we have an action of a given type in progress. private <T extends FeatureAction> boolean hasAction(final Class<T> clazz) { for (FeatureAction action : mActions) { if (action.getClass().equals(clazz)) { return true; } } return false; } /** * Remove the given {@link FeatureAction} object from the action queue. * Loading Loading @@ -415,36 +425,95 @@ public final class HdmiControlService extends SystemService { } @Override public void oneTouchPlay(IHdmiControlCallback callback) { public void oneTouchPlay(final IHdmiControlCallback callback) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#oneTouchPlay() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.oneTouchPlay(callback); } }); } @Override public void queryDisplayStatus(IHdmiControlCallback callback) { public void queryDisplayStatus(final IHdmiControlCallback callback) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#queryDisplayStatus() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.queryDisplayStatus(callback); } }); } @Override public void addHotplugEventListener(IHdmiHotplugEventListener listener) { public void addHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#addHotplugEventListener() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.addHotplugEventListener(listener); } }); } @Override public void removeHotplugEventListener(IHdmiHotplugEventListener listener) { public void removeHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#removeHotplugEventListener() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.removeHotplugEventListener(listener); } }); } } private void oneTouchPlay(IHdmiControlCallback callback) { // TODO: Create a new action if (hasAction(OneTouchPlayAction.class)) { Slog.w(TAG, "oneTouchPlay already in progress"); invokeCallback(callback, HdmiCec.RESULT_ALREADY_IN_PROGRESS); return; } HdmiCecLocalDevice source = mCecController.getLocalDevice(HdmiCec.DEVICE_PLAYBACK); if (source == null) { Slog.w(TAG, "Local playback device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } // TODO: Consider the case of multiple TV sets. For now we always direct the command // to the primary one. OneTouchPlayAction action = OneTouchPlayAction.create(this, source.getDeviceInfo().getLogicalAddress(), source.getDeviceInfo().getPhysicalAddress(), HdmiCec.ADDR_TV, callback); if (action == null) { Slog.w(TAG, "Cannot initiate oneTouchPlay"); invokeCallback(callback, HdmiCec.RESULT_EXCEPTION); return; } addAndStartAction(action); } private void queryDisplayStatus(IHdmiControlCallback callback) { // TODO: Create a new action if (hasAction(DevicePowerStatusAction.class)) { Slog.w(TAG, "queryDisplayStatus already in progress"); invokeCallback(callback, HdmiCec.RESULT_ALREADY_IN_PROGRESS); return; } HdmiCecLocalDevice source = mCecController.getLocalDevice(HdmiCec.DEVICE_PLAYBACK); if (source == null) { Slog.w(TAG, "Local playback device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } DevicePowerStatusAction action = DevicePowerStatusAction.create(this, source.getDeviceInfo().getLogicalAddress(), HdmiCec.ADDR_TV, callback); if (action == null) { Slog.w(TAG, "Cannot initiate queryDisplayStatus"); invokeCallback(callback, HdmiCec.RESULT_EXCEPTION); return; } addAndStartAction(action); } private void addHotplugEventListener(IHdmiHotplugEventListener listener) { Loading Loading @@ -473,4 +542,12 @@ public final class HdmiControlService extends SystemService { mHotplugEventListeners.remove(listener); } } private void invokeCallback(IHdmiControlCallback callback, int result) { try { callback.onComplete(result); } catch (RemoteException e) { Slog.e(TAG, "Invoking callback failed:" + e); } } } Loading
services/core/java/com/android/server/hdmi/HdmiCecController.java +18 −7 Original line number Diff line number Diff line Loading @@ -80,8 +80,8 @@ final class HdmiCecController { // A logical address of device is used as key of container. private final SparseArray<HdmiCecDeviceInfo> mDeviceInfos = new SparseArray<>(); // Stores the local CEC devices in the system. private final ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>(); // Stores the local CEC devices in the system. Device type is used for key. private final SparseArray<HdmiCecLocalDevice> mLocalDevices = new SparseArray<>(); // Private constructor. Use HdmiCecController.create(). private HdmiCecController() { Loading Loading @@ -131,7 +131,7 @@ final class HdmiCecController { // 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); mLocalDevices.put(type, device); device.init(); } } Loading Loading @@ -289,6 +289,17 @@ final class HdmiCecController { return mDeviceInfos.get(logicalAddress); } /** * Return the locally hosted logical device of a given type. * * @param deviceType logical device type * @return {@link HdmiCecLocalDevice} instance if the instance of the type is available; * otherwise null. */ HdmiCecLocalDevice getLocalDevice(int deviceType) { return mLocalDevices.get(deviceType); } /** * Add a new logical address to the device. Device's HW should be notified * when a new logical address is assigned to a device, so that it can accept Loading Loading @@ -317,8 +328,8 @@ final class HdmiCecController { assertRunOnServiceThread(); // TODO: consider to backup logical address so that new logical address // allocation can use it as preferred address. for (HdmiCecLocalDevice device : mLocalDevices) { device.clearAddress(); for (int i = 0; i < mLocalDevices.size(); ++i) { mLocalDevices.valueAt(i).clearAddress(); } nativeClearLogicalAddress(mNativePtr); } Loading Loading @@ -379,8 +390,8 @@ final class HdmiCecController { } private boolean isAllocatedLocalDeviceAddress(int address) { for (HdmiCecLocalDevice device : mLocalDevices) { if (device.isAddressOf(address)) { for (int i = 0; i < mLocalDevices.size(); ++i) { if (mLocalDevices.valueAt(i).isAddressOf(address)) { return true; } } Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +87 −10 Original line number Diff line number Diff line Loading @@ -178,6 +178,16 @@ public final class HdmiControlService extends SystemService { }); } // See if we have an action of a given type in progress. private <T extends FeatureAction> boolean hasAction(final Class<T> clazz) { for (FeatureAction action : mActions) { if (action.getClass().equals(clazz)) { return true; } } return false; } /** * Remove the given {@link FeatureAction} object from the action queue. * Loading Loading @@ -415,36 +425,95 @@ public final class HdmiControlService extends SystemService { } @Override public void oneTouchPlay(IHdmiControlCallback callback) { public void oneTouchPlay(final IHdmiControlCallback callback) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#oneTouchPlay() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.oneTouchPlay(callback); } }); } @Override public void queryDisplayStatus(IHdmiControlCallback callback) { public void queryDisplayStatus(final IHdmiControlCallback callback) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#queryDisplayStatus() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.queryDisplayStatus(callback); } }); } @Override public void addHotplugEventListener(IHdmiHotplugEventListener listener) { public void addHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#addHotplugEventListener() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.addHotplugEventListener(listener); } }); } @Override public void removeHotplugEventListener(IHdmiHotplugEventListener listener) { public void removeHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); // TODO: Post a message for HdmiControlService#removeHotplugEventListener() runOnServiceThread(new Runnable() { @Override public void run() { HdmiControlService.this.removeHotplugEventListener(listener); } }); } } private void oneTouchPlay(IHdmiControlCallback callback) { // TODO: Create a new action if (hasAction(OneTouchPlayAction.class)) { Slog.w(TAG, "oneTouchPlay already in progress"); invokeCallback(callback, HdmiCec.RESULT_ALREADY_IN_PROGRESS); return; } HdmiCecLocalDevice source = mCecController.getLocalDevice(HdmiCec.DEVICE_PLAYBACK); if (source == null) { Slog.w(TAG, "Local playback device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } // TODO: Consider the case of multiple TV sets. For now we always direct the command // to the primary one. OneTouchPlayAction action = OneTouchPlayAction.create(this, source.getDeviceInfo().getLogicalAddress(), source.getDeviceInfo().getPhysicalAddress(), HdmiCec.ADDR_TV, callback); if (action == null) { Slog.w(TAG, "Cannot initiate oneTouchPlay"); invokeCallback(callback, HdmiCec.RESULT_EXCEPTION); return; } addAndStartAction(action); } private void queryDisplayStatus(IHdmiControlCallback callback) { // TODO: Create a new action if (hasAction(DevicePowerStatusAction.class)) { Slog.w(TAG, "queryDisplayStatus already in progress"); invokeCallback(callback, HdmiCec.RESULT_ALREADY_IN_PROGRESS); return; } HdmiCecLocalDevice source = mCecController.getLocalDevice(HdmiCec.DEVICE_PLAYBACK); if (source == null) { Slog.w(TAG, "Local playback device not available"); invokeCallback(callback, HdmiCec.RESULT_SOURCE_NOT_AVAILABLE); return; } DevicePowerStatusAction action = DevicePowerStatusAction.create(this, source.getDeviceInfo().getLogicalAddress(), HdmiCec.ADDR_TV, callback); if (action == null) { Slog.w(TAG, "Cannot initiate queryDisplayStatus"); invokeCallback(callback, HdmiCec.RESULT_EXCEPTION); return; } addAndStartAction(action); } private void addHotplugEventListener(IHdmiHotplugEventListener listener) { Loading Loading @@ -473,4 +542,12 @@ public final class HdmiControlService extends SystemService { mHotplugEventListeners.remove(listener); } } private void invokeCallback(IHdmiControlCallback callback, int result) { try { callback.onComplete(result); } catch (RemoteException e) { Slog.e(TAG, "Invoking callback failed:" + e); } } }