diff --git a/services/core/java/com/android/server/hdmi/Constants.java b/services/core/java/com/android/server/hdmi/Constants.java index 4b812cf40067d..aa1310dd14c55 100644 --- a/services/core/java/com/android/server/hdmi/Constants.java +++ b/services/core/java/com/android/server/hdmi/Constants.java @@ -248,6 +248,11 @@ final class Constants { static final int DISABLED = 0; static final int ENABLED = 1; + // Property name for the local device configurations. + // TODO(OEM): OEM should provide this property, and the value is the comma separated integer + // values which denotes the device type in HDMI Spec 1.4. + static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type"; + // -------------------------------------------------- // MHL sub command message types. static final int MHL_MSG_MSGE = 0x02; @@ -275,11 +280,6 @@ final class Constants { static final int MHL_CBUS_MODE_ECBUS_S = 2; static final int MHL_CBUS_MODE_ECBUS_D = 3; - // Property name for the local device configurations. - // TODO(OEM): OEM should provide this property, and the value is the comma separated integer - // values which denotes the device type in HDMI Spec 1.4. - static final String PROPERTY_DEVICE_TYPE = "ro.hdmi.device_type"; - // MHL RCPE messages static final int MHL_RCPE_NO_ERROR = 0x00; static final int MHL_RCPE_INEFFECTIVE_KEYCODE = 0x01; diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index fcccfc0e5cccf..e7b920aa9a809 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -179,11 +179,6 @@ public final class HdmiControlService extends SystemService { private final ArrayList mVendorCommandListenerRecords = new ArrayList<>(); - // List of records for MHL Scratchpad command listener to handle the caller killed in action. - @GuardedBy("mLock") - private final ArrayList - mScratchpadCommandListenerRecords = new ArrayList<>(); - @GuardedBy("mLock") private InputChangeListenerRecord mInputChangeListenerRecord; @@ -201,13 +196,6 @@ public final class HdmiControlService extends SystemService { @GuardedBy("mLock") private boolean mProhibitMode; - // Set to true while the input change by MHL is allowed. - @GuardedBy("mLock") - private boolean mMhlInputChangeEnabled; - - @GuardedBy("mLock") - private List mMhlDevices; - // List of records for system audio mode change to handle the the caller killed in action. private final ArrayList mSystemAudioModeChangeListenerRecords = new ArrayList<>(); @@ -223,9 +211,6 @@ public final class HdmiControlService extends SystemService { @Nullable private HdmiCecController mCecController; - @Nullable - private HdmiMhlController mMhlController; - // HDMI port information. Stored in the unmodifiable list to keep the static information // from being modified. private List mPortInfo; @@ -256,8 +241,23 @@ public final class HdmiControlService extends SystemService { @ServiceThreadOnly private int mActivePortId = Constants.INVALID_PORT_ID; - // Last input port before switching to the MHL port by way of incoming request RAP[ContentOn]. - // Should switch back to this port when the device sends RAP[ContentOff]. + // Set to true while the input change by MHL is allowed. + @GuardedBy("mLock") + private boolean mMhlInputChangeEnabled; + + // List of records for MHL Scratchpad command listener to handle the caller killed in action. + @GuardedBy("mLock") + private final ArrayList + mScratchpadCommandListenerRecords = new ArrayList<>(); + + @GuardedBy("mLock") + private List mMhlDevices; + + @Nullable + private HdmiMhlController mMhlController; + + // Last input port before switching to the MHL port. Should switch back to this port + // when the mobile device sends the request one touch play with off. // Gets invalidated if we go to other port/input. @ServiceThreadOnly private int mLastInputMhl = Constants.INVALID_PORT_ID; @@ -304,16 +304,17 @@ public final class HdmiControlService extends SystemService { } mMhlController = HdmiMhlController.create(this); - if (mMhlController == null) { + if (!mMhlController.isReady()) { Slog.i(TAG, "Device does not support MHL-control."); } - initPortInfo(); mMhlDevices = Collections.emptyList(); + + initPortInfo(); mMessageValidator = new HdmiCecMessageValidator(this); publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService()); // Register broadcast receiver for power state change. - if (mCecController != null || mMhlController != null) { + if (mCecController != null) { IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); @@ -378,9 +379,7 @@ public final class HdmiControlService extends SystemService { setMhlInputChangeEnabled(enabled); break; case Global.MHL_POWER_CHARGE_ENABLED: - if (mMhlController != null) { - mMhlController.setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled)); - } + mMhlController.setOption(OPTION_MHL_POWER_CHARGE, toInt(enabled)); break; } } @@ -484,30 +483,30 @@ public final class HdmiControlService extends SystemService { mPortInfoMap = new UnmodifiableSparseArray<>(portInfoMap); mPortDeviceMap = new UnmodifiableSparseArray<>(portDeviceMap); - if (mMhlController == null) { + HdmiPortInfo[] mhlPortInfo = mMhlController.getPortInfos(); + ArraySet mhlSupportedPorts = new ArraySet(mhlPortInfo.length); + for (HdmiPortInfo info : mhlPortInfo) { + if (info.isMhlSupported()) { + mhlSupportedPorts.add(info.getId()); + } + } + + // Build HDMI port info list with CEC port info plus MHL supported flag. We can just use + // cec port info if we do not have have port that supports MHL. + if (mhlSupportedPorts.isEmpty()) { mPortInfo = Collections.unmodifiableList(Arrays.asList(cecPortInfo)); return; - } else { - HdmiPortInfo[] mhlPortInfo = mMhlController.getPortInfos(); - ArraySet mhlSupportedPorts = new ArraySet(mhlPortInfo.length); - for (HdmiPortInfo info : mhlPortInfo) { - if (info.isMhlSupported()) { - mhlSupportedPorts.add(info.getId()); - } - } - - // Build HDMI port info list with CEC port info plus MHL supported flag. - ArrayList result = new ArrayList<>(cecPortInfo.length); - for (HdmiPortInfo info : cecPortInfo) { - if (mhlSupportedPorts.contains(info.getId())) { - result.add(new HdmiPortInfo(info.getId(), info.getType(), info.getAddress(), - info.isCecSupported(), true, info.isArcSupported())); - } else { - result.add(info); - } - } - mPortInfo = Collections.unmodifiableList(result); } + ArrayList result = new ArrayList<>(cecPortInfo.length); + for (HdmiPortInfo info : cecPortInfo) { + if (mhlSupportedPorts.contains(info.getId())) { + result.add(new HdmiPortInfo(info.getId(), info.getType(), info.getAddress(), + info.isCecSupported(), true, info.isArcSupported())); + } else { + result.add(info); + } + } + mPortInfo = Collections.unmodifiableList(result); } List getPortInfo() { @@ -652,18 +651,6 @@ public final class HdmiControlService extends SystemService { sendCecCommand(command, null); } - @ServiceThreadOnly - void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) { - assertRunOnServiceThread(); - sendMhlSubcommand(portId, command, null); - } - - @ServiceThreadOnly - void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) { - assertRunOnServiceThread(); - mMhlController.sendSubcommand(portId, command, callback); - } - /** * Send command on the given CEC message if possible. * If the aborted message is invalid, then it wont send the message. @@ -795,6 +782,18 @@ public final class HdmiControlService extends SystemService { getVendorId(), displayName); } + @ServiceThreadOnly + void sendMhlSubcommand(int portId, HdmiMhlSubcommand command) { + assertRunOnServiceThread(); + sendMhlSubcommand(portId, command, null); + } + + @ServiceThreadOnly + void sendMhlSubcommand(int portId, HdmiMhlSubcommand command, SendMessageCallback callback) { + assertRunOnServiceThread(); + mMhlController.sendSubcommand(portId, command, callback); + } + @ServiceThreadOnly boolean handleMhlSubcommand(int portId, HdmiMhlSubcommand message) { assertRunOnServiceThread(); @@ -895,6 +894,19 @@ public final class HdmiControlService extends SystemService { return mMhlDevices; } + private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient { + private final IHdmiMhlScratchpadCommandListener mListener; + + public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) { + mListener = listener; + } + + @Override + public void binderDied() { + mScratchpadCommandListenerRecords.remove(this); + } + } + // Record class that monitors the event of the caller of being killed. Used to clean up // the listener list and record list accordingly. private final class HotplugEventListenerRecord implements IBinder.DeathRecipient { @@ -974,19 +986,6 @@ public final class HdmiControlService extends SystemService { } } - private class HdmiMhlScratchpadCommandListenerRecord implements IBinder.DeathRecipient { - private final IHdmiMhlScratchpadCommandListener mListener; - - public HdmiMhlScratchpadCommandListenerRecord(IHdmiMhlScratchpadCommandListener listener) { - mListener = listener; - } - - @Override - public void binderDied() { - mScratchpadCommandListenerRecords.remove(this); - } - } - private void enforceAccessPermission() { getContext().enforceCallingOrSelfPermission(PERMISSION, TAG); } @@ -1039,20 +1038,18 @@ public final class HdmiControlService extends SystemService { invokeCallback(callback, HdmiControlManager.RESULT_SOURCE_NOT_AVAILABLE); return; } - if (mMhlController != null) { - HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId); - if (device != null) { - if (device.getPortId() == tv.getActivePortId()) { - invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); - return; - } - // Upon selecting MHL device, we send RAP[Content On] to wake up - // the connected mobile device, start routing control to switch ports. - // callback is handled by MHL action. - device.turnOn(callback); - tv.doManualPortSwitching(device.getInfo().getPortId(), null); + HdmiMhlLocalDevice device = mMhlController.getLocalDeviceById(deviceId); + if (device != null) { + if (device.getPortId() == tv.getActivePortId()) { + invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS); return; } + // Upon selecting MHL device, we send RAP[Content On] to wake up + // the connected mobile device, start routing control to switch ports. + // callback is handled by MHL action. + device.turnOn(callback); + tv.doManualPortSwitching(device.getInfo().getPortId(), null); + return; } tv.deviceSelect(deviceId, callback); } @@ -1086,12 +1083,10 @@ public final class HdmiControlService extends SystemService { runOnServiceThread(new Runnable() { @Override public void run() { - if (mMhlController != null) { - HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId); - if (device != null) { - device.sendKeyEvent(keyCode, isPressed); - return; - } + HdmiMhlLocalDevice device = mMhlController.getLocalDevice(mActivePortId); + if (device != null) { + device.sendKeyEvent(keyCode, isPressed); + return; } if (mCecController != null) { HdmiCecLocalDevice localDevice = mCecController.getLocalDevice(deviceType); @@ -1380,10 +1375,6 @@ public final class HdmiControlService extends SystemService { runOnServiceThread(new Runnable() { @Override public void run() { - if (mMhlController == null) { - Slog.w(TAG, "No Mhl controller available."); - return; - } if (!isControlEnabled()) { Slog.w(TAG, "Hdmi control is disabled."); return ; @@ -1775,9 +1766,7 @@ public final class HdmiControlService extends SystemService { } } - if (mMhlController != null) { - mMhlController.clearAllLocalDevices(); - } + mMhlController.clearAllLocalDevices(); } @ServiceThreadOnly @@ -1887,9 +1876,7 @@ public final class HdmiControlService extends SystemService { int value = toInt(enabled); mCecController.setOption(OPTION_CEC_ENABLE, value); - if (mMhlController != null) { - mMhlController.setOption(OPTION_MHL_ENABLE, value); - } + mMhlController.setOption(OPTION_MHL_ENABLE, value); synchronized (mLock) { mHdmiControlEnabled = enabled; @@ -1955,7 +1942,7 @@ public final class HdmiControlService extends SystemService { tv().setActivePortId(portId); // The port is either the MHL-enabled port where the mobile device is connected, or - // the last port to go back to when RAP[ContentOff] is received. Note that the last port + // the last port to go back to when turnoff command is received. Note that the last port // may not be the MHL-enabled one. In this case the device info to be passed to // input change listener should be the one describing the corresponding HDMI port. HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId); @@ -1966,9 +1953,7 @@ public final class HdmiControlService extends SystemService { } void setMhlInputChangeEnabled(boolean enabled) { - if (mMhlController != null) { - mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled)); - } + mMhlController.setOption(OPTION_MHL_INPUT_SWITCHING, toInt(enabled)); synchronized (mLock) { mMhlInputChangeEnabled = enabled;