Loading services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java +13 −8 Original line number Diff line number Diff line Loading @@ -38,10 +38,12 @@ public class HdmiCecAtomWriter { * @param message The HDMI CEC message * @param direction Whether the message is incoming, outgoing, or neither * @param errorCode The error code from the final attempt to send the message * @param callingUid The calling uid of the app that triggered this message */ public void messageReported(HdmiCecMessage message, int direction, int errorCode) { public void messageReported( HdmiCecMessage message, int direction, int callingUid, int errorCode) { MessageReportedGenericArgs genericArgs = createMessageReportedGenericArgs( message, direction, errorCode); message, direction, errorCode, callingUid); MessageReportedSpecialArgs specialArgs = createMessageReportedSpecialArgs(message); messageReportedBase(genericArgs, specialArgs); } Loading @@ -51,9 +53,10 @@ public class HdmiCecAtomWriter { * * @param message The HDMI CEC message * @param direction Whether the message is incoming, outgoing, or neither * @param callingUid The calling uid of the app that triggered this message */ public void messageReported(HdmiCecMessage message, int direction) { messageReported(message, direction, ERROR_CODE_UNKNOWN); public void messageReported(HdmiCecMessage message, int direction, int callingUid) { messageReported(message, direction, callingUid, ERROR_CODE_UNKNOWN); } /** Loading @@ -65,11 +68,11 @@ public class HdmiCecAtomWriter { * otherwise, ERROR_CODE_UNKNOWN */ private MessageReportedGenericArgs createMessageReportedGenericArgs( HdmiCecMessage message, int direction, int errorCode) { HdmiCecMessage message, int direction, int errorCode, int callingUid) { int sendMessageResult = errorCode == ERROR_CODE_UNKNOWN ? HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN : errorCode + 10; return new MessageReportedGenericArgs(direction, message.getSource(), return new MessageReportedGenericArgs(callingUid, direction, message.getSource(), message.getDestination(), message.getOpcode(), sendMessageResult); } Loading Loading @@ -134,7 +137,7 @@ public class HdmiCecAtomWriter { MessageReportedSpecialArgs specialArgs) { FrameworkStatsLog.write( FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED, 0, // Placeholder field genericArgs.mUid, genericArgs.mDirection, genericArgs.mInitiatorLogicalAddress, genericArgs.mDestinationLogicalAddress, Loading Loading @@ -167,14 +170,16 @@ public class HdmiCecAtomWriter { * Contains the required arguments for creating any HdmiCecMessageReported atom */ private class MessageReportedGenericArgs { final int mUid; final int mDirection; final int mInitiatorLogicalAddress; final int mDestinationLogicalAddress; final int mOpcode; final int mSendMessageResult; MessageReportedGenericArgs(int direction, int initiatorLogicalAddress, MessageReportedGenericArgs(int uid, int direction, int initiatorLogicalAddress, int destinationLogicalAddress, int opcode, int sendMessageResult) { this.mUid = uid; this.mDirection = direction; this.mInitiatorLogicalAddress = initiatorLogicalAddress; this.mDestinationLogicalAddress = destinationLogicalAddress; Loading services/core/java/com/android/server/hdmi/HdmiCecController.java +21 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.hardware.tv.cec.V1_0.Result; import android.hardware.tv.cec.V1_0.SendMessageResult; import android.icu.util.IllformedLocaleException; import android.icu.util.ULocale; import android.os.Binder; import android.os.Handler; import android.os.IHwBinder; import android.os.Looper; Loading Loading @@ -525,12 +526,14 @@ final class HdmiCecController { // Run a Runnable on IO thread. // It should be careful to access member variables on IO thread because // it can be accessed from system thread as well. private void runOnIoThread(Runnable runnable) { mIoHandler.post(runnable); @VisibleForTesting void runOnIoThread(Runnable runnable) { mIoHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } private void runOnServiceThread(Runnable runnable) { mControlHandler.post(runnable); @VisibleForTesting void runOnServiceThread(Runnable runnable) { mControlHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } @ServiceThreadOnly Loading Loading @@ -591,6 +594,18 @@ final class HdmiCecController { sendCommand(cecMessage, null); } /** * Returns the calling UID of the original Binder call that triggered this code. * If this code was not triggered by a Binder call, returns the UID of this process. */ private int getCallingUid() { int workSourceUid = Binder.getCallingWorkSourceUid(); if (workSourceUid == -1) { return Binder.getCallingUid(); } return workSourceUid; } @ServiceThreadOnly void sendCommand(final HdmiCecMessage cecMessage, final HdmiControlService.SendMessageCallback callback) { Loading Loading @@ -621,6 +636,7 @@ final class HdmiCecController { mHdmiCecAtomWriter.messageReported( cecMessage, FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED__DIRECTION__OUTGOING, getCallingUid(), finalError ); if (callback != null) { Loading @@ -643,7 +659,7 @@ final class HdmiCecController { addCecMessageToHistory(true /* isReceived */, command); mHdmiCecAtomWriter.messageReported(command, incomingMessageDirection(srcAddress, dstAddress)); incomingMessageDirection(srcAddress, dstAddress), getCallingUid()); onReceiveCommand(command); } Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +80 −62 Original line number Diff line number Diff line Loading @@ -991,12 +991,14 @@ public class HdmiControlService extends SystemService { return mCecController.isConnected(portId); } /** * Executes a Runnable on the service thread. * During execution, sets the work source UID to the parent's work source UID. * * @param runnable The runnable to execute on the service thread */ void runOnServiceThread(Runnable runnable) { mHandler.post(runnable); } void runOnServiceThreadAtFrontOfQueue(Runnable runnable) { mHandler.postAtFrontOfQueue(runnable); mHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } private void assertRunOnServiceThread() { Loading Loading @@ -1475,14 +1477,30 @@ public class HdmiControlService extends SystemService { } } /** * Sets the work source UID to the Binder calling UID. * Work source UID allows access to the original calling UID of a Binder call in the Runnables * that it spawns. * This is necessary because Runnables that are executed on the service thread * take on the calling UID of the service thread. */ private void setWorkSourceUidToCallingUid() { Binder.setCallingWorkSourceUid(Binder.getCallingUid()); } private void enforceAccessPermission() { getContext().enforceCallingOrSelfPermission(PERMISSION, TAG); } private void initBinderCall() { enforceAccessPermission(); setWorkSourceUidToCallingUid(); } private final class BinderService extends IHdmiControlService.Stub { @Override public int[] getSupportedTypes() { enforceAccessPermission(); initBinderCall(); // mLocalDevices is an unmodifiable list - no lock necesary. int[] localDevices = new int[mLocalDevices.size()]; for (int i = 0; i < localDevices.length; ++i) { Loading @@ -1494,14 +1512,14 @@ public class HdmiControlService extends SystemService { @Override @Nullable public HdmiDeviceInfo getActiveSource() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.getActiveSource(); } @Override public void deviceSelect(final int deviceId, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -1548,7 +1566,7 @@ public class HdmiControlService extends SystemService { @Override public void portSelect(final int portId, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -1586,7 +1604,7 @@ public class HdmiControlService extends SystemService { @Override public void sendKeyEvent(final int deviceType, final int keyCode, final boolean isPressed) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1610,7 +1628,7 @@ public class HdmiControlService extends SystemService { @Override public void sendVolumeKeyEvent( final int deviceType, final int keyCode, final boolean isPressed) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1631,7 +1649,7 @@ public class HdmiControlService extends SystemService { @Override public void oneTouchPlay(final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); int pid = Binder.getCallingPid(); Slog.d(TAG, "Process pid: " + pid + " is calling oneTouchPlay."); runOnServiceThread(new Runnable() { Loading @@ -1644,7 +1662,7 @@ public class HdmiControlService extends SystemService { @Override public void toggleAndFollowTvPower() { enforceAccessPermission(); initBinderCall(); int pid = Binder.getCallingPid(); Slog.d(TAG, "Process pid: " + pid + " is calling toggleAndFollowTvPower."); runOnServiceThread(new Runnable() { Loading @@ -1657,13 +1675,13 @@ public class HdmiControlService extends SystemService { @Override public boolean shouldHandleTvPowerKey() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.shouldHandleTvPowerKey(); } @Override public void queryDisplayStatus(final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1675,53 +1693,53 @@ public class HdmiControlService extends SystemService { @Override public void addHdmiControlStatusChangeListener( final IHdmiControlStatusChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiControlStatusChangeListener(listener); } @Override public void removeHdmiControlStatusChangeListener( final IHdmiControlStatusChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHdmiControlStatusChangeListener(listener); } @Override public void addHdmiCecVolumeControlFeatureListener( final IHdmiCecVolumeControlFeatureListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiCecVolumeControlFeatureListener(listener); } @Override public void removeHdmiCecVolumeControlFeatureListener( final IHdmiCecVolumeControlFeatureListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHdmiControlVolumeControlStatusChangeListener(listener); } @Override public void addHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHotplugEventListener(listener); } @Override public void removeHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHotplugEventListener(listener); } @Override public void addDeviceEventListener(final IHdmiDeviceEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addDeviceEventListener(listener); } @Override public List<HdmiPortInfo> getPortInfo() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.getPortInfo() == null ? Collections.<HdmiPortInfo>emptyList() : HdmiControlService.this.getPortInfo(); Loading @@ -1729,7 +1747,7 @@ public class HdmiControlService extends SystemService { @Override public boolean canChangeSystemAudioMode() { enforceAccessPermission(); initBinderCall(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; Loading @@ -1740,7 +1758,7 @@ public class HdmiControlService extends SystemService { @Override public boolean getSystemAudioMode() { // TODO(shubang): handle getSystemAudioMode() for all device types enforceAccessPermission(); initBinderCall(); HdmiCecLocalDeviceTv tv = tv(); HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); return (tv != null && tv.isSystemAudioActivated()) Loading @@ -1749,7 +1767,7 @@ public class HdmiControlService extends SystemService { @Override public int getPhysicalAddress() { enforceAccessPermission(); initBinderCall(); synchronized (mLock) { return mHdmiCecNetwork.getPhysicalAddress(); } Loading @@ -1757,7 +1775,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioMode(final boolean enabled, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1775,26 +1793,26 @@ public class HdmiControlService extends SystemService { @Override public void addSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addSystemAudioModeChangeListner(listener); } @Override public void removeSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeSystemAudioModeChangeListener(listener); } @Override public void setInputChangeListener(final IHdmiInputChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.setInputChangeListener(listener); } @Override public List<HdmiDeviceInfo> getInputDevices() { enforceAccessPermission(); initBinderCall(); // No need to hold the lock for obtaining TV device as the local device instance // is preserved while the HDMI control is enabled. return HdmiUtils.mergeToUnmodifiableList(mHdmiCecNetwork.getSafeExternalInputsLocked(), Loading @@ -1805,13 +1823,13 @@ public class HdmiControlService extends SystemService { // even those of reserved type. @Override public List<HdmiDeviceInfo> getDeviceList() { enforceAccessPermission(); initBinderCall(); return mHdmiCecNetwork.getSafeCecDevicesLocked(); } @Override public void powerOffRemoteDevice(int logicalAddress, int powerStatus) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1826,7 +1844,7 @@ public class HdmiControlService extends SystemService { @Override public void powerOnRemoteDevice(int logicalAddress, int powerStatus) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1846,7 +1864,7 @@ public class HdmiControlService extends SystemService { @Override // TODO(b/128427908): add a result callback public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1867,7 +1885,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioVolume(final int oldIndex, final int newIndex, final int maxIndex) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1883,7 +1901,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioMute(final boolean mute) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1899,7 +1917,7 @@ public class HdmiControlService extends SystemService { @Override public void setArcMode(final boolean enabled) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1914,7 +1932,7 @@ public class HdmiControlService extends SystemService { @Override public void setProhibitMode(final boolean enabled) { enforceAccessPermission(); initBinderCall(); if (!isTvDevice()) { return; } Loading @@ -1924,14 +1942,14 @@ public class HdmiControlService extends SystemService { @Override public void addVendorCommandListener(final IHdmiVendorCommandListener listener, final int deviceType) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addVendorCommandListener(listener, deviceType); } @Override public void sendVendorCommand(final int deviceType, final int targetAddress, final byte[] params, final boolean hasVendorId) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1954,7 +1972,7 @@ public class HdmiControlService extends SystemService { @Override public void sendStandby(final int deviceType, final int deviceId) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1978,13 +1996,13 @@ public class HdmiControlService extends SystemService { @Override public void setHdmiRecordListener(IHdmiRecordListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.setHdmiRecordListener(listener); } @Override public void startOneTouchRecord(final int recorderAddress, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1999,7 +2017,7 @@ public class HdmiControlService extends SystemService { @Override public void stopOneTouchRecord(final int recorderAddress) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2015,7 +2033,7 @@ public class HdmiControlService extends SystemService { @Override public void startTimerRecording(final int recorderAddress, final int sourceType, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2031,7 +2049,7 @@ public class HdmiControlService extends SystemService { @Override public void clearTimerRecording(final int recorderAddress, final int sourceType, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2047,7 +2065,7 @@ public class HdmiControlService extends SystemService { @Override public void sendMhlVendorCommand(final int portId, final int offset, final int length, final byte[] data) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2068,13 +2086,13 @@ public class HdmiControlService extends SystemService { @Override public void addHdmiMhlVendorCommandListener( IHdmiMhlVendorCommandListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiMhlVendorCommandListener(listener); } @Override public void setStandbyMode(final boolean isStandbyModeOn) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2085,13 +2103,13 @@ public class HdmiControlService extends SystemService { @Override public boolean isHdmiCecVolumeControlEnabled() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.isHdmiCecVolumeControlEnabled(); } @Override public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) { enforceAccessPermission(); initBinderCall(); final long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.setHdmiCecVolumeControlEnabled( Loading @@ -2104,7 +2122,7 @@ public class HdmiControlService extends SystemService { @Override public void reportAudioStatus(final int deviceType, final int volume, final int maxVolume, final boolean isMute) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2128,7 +2146,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioModeOnForAudioOnlySource() { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -2156,7 +2174,7 @@ public class HdmiControlService extends SystemService { @Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { enforceAccessPermission(); initBinderCall(); new HdmiControlShellCommand(this) .exec(this, in, out, err, args, callback, resultReceiver); } Loading Loading @@ -2212,7 +2230,7 @@ public class HdmiControlService extends SystemService { @Override public List<String> getUserCecSettings() { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getUserSettings(); Loading @@ -2223,7 +2241,7 @@ public class HdmiControlService extends SystemService { @Override public List<String> getAllowedCecSettingStringValues(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getAllowedStringValues(name); Loading @@ -2234,7 +2252,7 @@ public class HdmiControlService extends SystemService { @Override public int[] getAllowedCecSettingIntValues(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { List<Integer> allowedValues = Loading @@ -2247,7 +2265,7 @@ public class HdmiControlService extends SystemService { @Override public String getCecSettingStringValue(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getStringValue(name); Loading @@ -2258,7 +2276,7 @@ public class HdmiControlService extends SystemService { @Override public void setCecSettingStringValue(String name, String value) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.getHdmiCecConfig().setStringValue(name, value); Loading @@ -2269,7 +2287,7 @@ public class HdmiControlService extends SystemService { @Override public int getCecSettingIntValue(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getIntValue(name); Loading @@ -2280,7 +2298,7 @@ public class HdmiControlService extends SystemService { @Override public void setCecSettingIntValue(String name, int value) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.getHdmiCecConfig().setIntValue(name, value); Loading Loading
services/core/java/com/android/server/hdmi/HdmiCecAtomWriter.java +13 −8 Original line number Diff line number Diff line Loading @@ -38,10 +38,12 @@ public class HdmiCecAtomWriter { * @param message The HDMI CEC message * @param direction Whether the message is incoming, outgoing, or neither * @param errorCode The error code from the final attempt to send the message * @param callingUid The calling uid of the app that triggered this message */ public void messageReported(HdmiCecMessage message, int direction, int errorCode) { public void messageReported( HdmiCecMessage message, int direction, int callingUid, int errorCode) { MessageReportedGenericArgs genericArgs = createMessageReportedGenericArgs( message, direction, errorCode); message, direction, errorCode, callingUid); MessageReportedSpecialArgs specialArgs = createMessageReportedSpecialArgs(message); messageReportedBase(genericArgs, specialArgs); } Loading @@ -51,9 +53,10 @@ public class HdmiCecAtomWriter { * * @param message The HDMI CEC message * @param direction Whether the message is incoming, outgoing, or neither * @param callingUid The calling uid of the app that triggered this message */ public void messageReported(HdmiCecMessage message, int direction) { messageReported(message, direction, ERROR_CODE_UNKNOWN); public void messageReported(HdmiCecMessage message, int direction, int callingUid) { messageReported(message, direction, callingUid, ERROR_CODE_UNKNOWN); } /** Loading @@ -65,11 +68,11 @@ public class HdmiCecAtomWriter { * otherwise, ERROR_CODE_UNKNOWN */ private MessageReportedGenericArgs createMessageReportedGenericArgs( HdmiCecMessage message, int direction, int errorCode) { HdmiCecMessage message, int direction, int errorCode, int callingUid) { int sendMessageResult = errorCode == ERROR_CODE_UNKNOWN ? HdmiStatsEnums.SEND_MESSAGE_RESULT_UNKNOWN : errorCode + 10; return new MessageReportedGenericArgs(direction, message.getSource(), return new MessageReportedGenericArgs(callingUid, direction, message.getSource(), message.getDestination(), message.getOpcode(), sendMessageResult); } Loading Loading @@ -134,7 +137,7 @@ public class HdmiCecAtomWriter { MessageReportedSpecialArgs specialArgs) { FrameworkStatsLog.write( FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED, 0, // Placeholder field genericArgs.mUid, genericArgs.mDirection, genericArgs.mInitiatorLogicalAddress, genericArgs.mDestinationLogicalAddress, Loading Loading @@ -167,14 +170,16 @@ public class HdmiCecAtomWriter { * Contains the required arguments for creating any HdmiCecMessageReported atom */ private class MessageReportedGenericArgs { final int mUid; final int mDirection; final int mInitiatorLogicalAddress; final int mDestinationLogicalAddress; final int mOpcode; final int mSendMessageResult; MessageReportedGenericArgs(int direction, int initiatorLogicalAddress, MessageReportedGenericArgs(int uid, int direction, int initiatorLogicalAddress, int destinationLogicalAddress, int opcode, int sendMessageResult) { this.mUid = uid; this.mDirection = direction; this.mInitiatorLogicalAddress = initiatorLogicalAddress; this.mDestinationLogicalAddress = destinationLogicalAddress; Loading
services/core/java/com/android/server/hdmi/HdmiCecController.java +21 −5 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.hardware.tv.cec.V1_0.Result; import android.hardware.tv.cec.V1_0.SendMessageResult; import android.icu.util.IllformedLocaleException; import android.icu.util.ULocale; import android.os.Binder; import android.os.Handler; import android.os.IHwBinder; import android.os.Looper; Loading Loading @@ -525,12 +526,14 @@ final class HdmiCecController { // Run a Runnable on IO thread. // It should be careful to access member variables on IO thread because // it can be accessed from system thread as well. private void runOnIoThread(Runnable runnable) { mIoHandler.post(runnable); @VisibleForTesting void runOnIoThread(Runnable runnable) { mIoHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } private void runOnServiceThread(Runnable runnable) { mControlHandler.post(runnable); @VisibleForTesting void runOnServiceThread(Runnable runnable) { mControlHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } @ServiceThreadOnly Loading Loading @@ -591,6 +594,18 @@ final class HdmiCecController { sendCommand(cecMessage, null); } /** * Returns the calling UID of the original Binder call that triggered this code. * If this code was not triggered by a Binder call, returns the UID of this process. */ private int getCallingUid() { int workSourceUid = Binder.getCallingWorkSourceUid(); if (workSourceUid == -1) { return Binder.getCallingUid(); } return workSourceUid; } @ServiceThreadOnly void sendCommand(final HdmiCecMessage cecMessage, final HdmiControlService.SendMessageCallback callback) { Loading Loading @@ -621,6 +636,7 @@ final class HdmiCecController { mHdmiCecAtomWriter.messageReported( cecMessage, FrameworkStatsLog.HDMI_CEC_MESSAGE_REPORTED__DIRECTION__OUTGOING, getCallingUid(), finalError ); if (callback != null) { Loading @@ -643,7 +659,7 @@ final class HdmiCecController { addCecMessageToHistory(true /* isReceived */, command); mHdmiCecAtomWriter.messageReported(command, incomingMessageDirection(srcAddress, dstAddress)); incomingMessageDirection(srcAddress, dstAddress), getCallingUid()); onReceiveCommand(command); } Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +80 −62 Original line number Diff line number Diff line Loading @@ -991,12 +991,14 @@ public class HdmiControlService extends SystemService { return mCecController.isConnected(portId); } /** * Executes a Runnable on the service thread. * During execution, sets the work source UID to the parent's work source UID. * * @param runnable The runnable to execute on the service thread */ void runOnServiceThread(Runnable runnable) { mHandler.post(runnable); } void runOnServiceThreadAtFrontOfQueue(Runnable runnable) { mHandler.postAtFrontOfQueue(runnable); mHandler.post(new WorkSourceUidPreservingRunnable(runnable)); } private void assertRunOnServiceThread() { Loading Loading @@ -1475,14 +1477,30 @@ public class HdmiControlService extends SystemService { } } /** * Sets the work source UID to the Binder calling UID. * Work source UID allows access to the original calling UID of a Binder call in the Runnables * that it spawns. * This is necessary because Runnables that are executed on the service thread * take on the calling UID of the service thread. */ private void setWorkSourceUidToCallingUid() { Binder.setCallingWorkSourceUid(Binder.getCallingUid()); } private void enforceAccessPermission() { getContext().enforceCallingOrSelfPermission(PERMISSION, TAG); } private void initBinderCall() { enforceAccessPermission(); setWorkSourceUidToCallingUid(); } private final class BinderService extends IHdmiControlService.Stub { @Override public int[] getSupportedTypes() { enforceAccessPermission(); initBinderCall(); // mLocalDevices is an unmodifiable list - no lock necesary. int[] localDevices = new int[mLocalDevices.size()]; for (int i = 0; i < localDevices.length; ++i) { Loading @@ -1494,14 +1512,14 @@ public class HdmiControlService extends SystemService { @Override @Nullable public HdmiDeviceInfo getActiveSource() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.getActiveSource(); } @Override public void deviceSelect(final int deviceId, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -1548,7 +1566,7 @@ public class HdmiControlService extends SystemService { @Override public void portSelect(final int portId, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -1586,7 +1604,7 @@ public class HdmiControlService extends SystemService { @Override public void sendKeyEvent(final int deviceType, final int keyCode, final boolean isPressed) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1610,7 +1628,7 @@ public class HdmiControlService extends SystemService { @Override public void sendVolumeKeyEvent( final int deviceType, final int keyCode, final boolean isPressed) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1631,7 +1649,7 @@ public class HdmiControlService extends SystemService { @Override public void oneTouchPlay(final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); int pid = Binder.getCallingPid(); Slog.d(TAG, "Process pid: " + pid + " is calling oneTouchPlay."); runOnServiceThread(new Runnable() { Loading @@ -1644,7 +1662,7 @@ public class HdmiControlService extends SystemService { @Override public void toggleAndFollowTvPower() { enforceAccessPermission(); initBinderCall(); int pid = Binder.getCallingPid(); Slog.d(TAG, "Process pid: " + pid + " is calling toggleAndFollowTvPower."); runOnServiceThread(new Runnable() { Loading @@ -1657,13 +1675,13 @@ public class HdmiControlService extends SystemService { @Override public boolean shouldHandleTvPowerKey() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.shouldHandleTvPowerKey(); } @Override public void queryDisplayStatus(final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1675,53 +1693,53 @@ public class HdmiControlService extends SystemService { @Override public void addHdmiControlStatusChangeListener( final IHdmiControlStatusChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiControlStatusChangeListener(listener); } @Override public void removeHdmiControlStatusChangeListener( final IHdmiControlStatusChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHdmiControlStatusChangeListener(listener); } @Override public void addHdmiCecVolumeControlFeatureListener( final IHdmiCecVolumeControlFeatureListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiCecVolumeControlFeatureListener(listener); } @Override public void removeHdmiCecVolumeControlFeatureListener( final IHdmiCecVolumeControlFeatureListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHdmiControlVolumeControlStatusChangeListener(listener); } @Override public void addHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHotplugEventListener(listener); } @Override public void removeHotplugEventListener(final IHdmiHotplugEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeHotplugEventListener(listener); } @Override public void addDeviceEventListener(final IHdmiDeviceEventListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addDeviceEventListener(listener); } @Override public List<HdmiPortInfo> getPortInfo() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.getPortInfo() == null ? Collections.<HdmiPortInfo>emptyList() : HdmiControlService.this.getPortInfo(); Loading @@ -1729,7 +1747,7 @@ public class HdmiControlService extends SystemService { @Override public boolean canChangeSystemAudioMode() { enforceAccessPermission(); initBinderCall(); HdmiCecLocalDeviceTv tv = tv(); if (tv == null) { return false; Loading @@ -1740,7 +1758,7 @@ public class HdmiControlService extends SystemService { @Override public boolean getSystemAudioMode() { // TODO(shubang): handle getSystemAudioMode() for all device types enforceAccessPermission(); initBinderCall(); HdmiCecLocalDeviceTv tv = tv(); HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem(); return (tv != null && tv.isSystemAudioActivated()) Loading @@ -1749,7 +1767,7 @@ public class HdmiControlService extends SystemService { @Override public int getPhysicalAddress() { enforceAccessPermission(); initBinderCall(); synchronized (mLock) { return mHdmiCecNetwork.getPhysicalAddress(); } Loading @@ -1757,7 +1775,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioMode(final boolean enabled, final IHdmiControlCallback callback) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1775,26 +1793,26 @@ public class HdmiControlService extends SystemService { @Override public void addSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addSystemAudioModeChangeListner(listener); } @Override public void removeSystemAudioModeChangeListener( final IHdmiSystemAudioModeChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.removeSystemAudioModeChangeListener(listener); } @Override public void setInputChangeListener(final IHdmiInputChangeListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.setInputChangeListener(listener); } @Override public List<HdmiDeviceInfo> getInputDevices() { enforceAccessPermission(); initBinderCall(); // No need to hold the lock for obtaining TV device as the local device instance // is preserved while the HDMI control is enabled. return HdmiUtils.mergeToUnmodifiableList(mHdmiCecNetwork.getSafeExternalInputsLocked(), Loading @@ -1805,13 +1823,13 @@ public class HdmiControlService extends SystemService { // even those of reserved type. @Override public List<HdmiDeviceInfo> getDeviceList() { enforceAccessPermission(); initBinderCall(); return mHdmiCecNetwork.getSafeCecDevicesLocked(); } @Override public void powerOffRemoteDevice(int logicalAddress, int powerStatus) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1826,7 +1844,7 @@ public class HdmiControlService extends SystemService { @Override public void powerOnRemoteDevice(int logicalAddress, int powerStatus) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1846,7 +1864,7 @@ public class HdmiControlService extends SystemService { @Override // TODO(b/128427908): add a result callback public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1867,7 +1885,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioVolume(final int oldIndex, final int newIndex, final int maxIndex) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1883,7 +1901,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioMute(final boolean mute) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1899,7 +1917,7 @@ public class HdmiControlService extends SystemService { @Override public void setArcMode(final boolean enabled) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1914,7 +1932,7 @@ public class HdmiControlService extends SystemService { @Override public void setProhibitMode(final boolean enabled) { enforceAccessPermission(); initBinderCall(); if (!isTvDevice()) { return; } Loading @@ -1924,14 +1942,14 @@ public class HdmiControlService extends SystemService { @Override public void addVendorCommandListener(final IHdmiVendorCommandListener listener, final int deviceType) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addVendorCommandListener(listener, deviceType); } @Override public void sendVendorCommand(final int deviceType, final int targetAddress, final byte[] params, final boolean hasVendorId) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1954,7 +1972,7 @@ public class HdmiControlService extends SystemService { @Override public void sendStandby(final int deviceType, final int deviceId) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1978,13 +1996,13 @@ public class HdmiControlService extends SystemService { @Override public void setHdmiRecordListener(IHdmiRecordListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.setHdmiRecordListener(listener); } @Override public void startOneTouchRecord(final int recorderAddress, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -1999,7 +2017,7 @@ public class HdmiControlService extends SystemService { @Override public void stopOneTouchRecord(final int recorderAddress) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2015,7 +2033,7 @@ public class HdmiControlService extends SystemService { @Override public void startTimerRecording(final int recorderAddress, final int sourceType, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2031,7 +2049,7 @@ public class HdmiControlService extends SystemService { @Override public void clearTimerRecording(final int recorderAddress, final int sourceType, final byte[] recordSource) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2047,7 +2065,7 @@ public class HdmiControlService extends SystemService { @Override public void sendMhlVendorCommand(final int portId, final int offset, final int length, final byte[] data) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2068,13 +2086,13 @@ public class HdmiControlService extends SystemService { @Override public void addHdmiMhlVendorCommandListener( IHdmiMhlVendorCommandListener listener) { enforceAccessPermission(); initBinderCall(); HdmiControlService.this.addHdmiMhlVendorCommandListener(listener); } @Override public void setStandbyMode(final boolean isStandbyModeOn) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2085,13 +2103,13 @@ public class HdmiControlService extends SystemService { @Override public boolean isHdmiCecVolumeControlEnabled() { enforceAccessPermission(); initBinderCall(); return HdmiControlService.this.isHdmiCecVolumeControlEnabled(); } @Override public void setHdmiCecVolumeControlEnabled(final boolean isHdmiCecVolumeControlEnabled) { enforceAccessPermission(); initBinderCall(); final long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.setHdmiCecVolumeControlEnabled( Loading @@ -2104,7 +2122,7 @@ public class HdmiControlService extends SystemService { @Override public void reportAudioStatus(final int deviceType, final int volume, final int maxVolume, final boolean isMute) { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading @@ -2128,7 +2146,7 @@ public class HdmiControlService extends SystemService { @Override public void setSystemAudioModeOnForAudioOnlySource() { enforceAccessPermission(); initBinderCall(); runOnServiceThread(new Runnable() { @Override public void run() { Loading Loading @@ -2156,7 +2174,7 @@ public class HdmiControlService extends SystemService { @Nullable FileDescriptor err, String[] args, @Nullable ShellCallback callback, ResultReceiver resultReceiver) throws RemoteException { enforceAccessPermission(); initBinderCall(); new HdmiControlShellCommand(this) .exec(this, in, out, err, args, callback, resultReceiver); } Loading Loading @@ -2212,7 +2230,7 @@ public class HdmiControlService extends SystemService { @Override public List<String> getUserCecSettings() { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getUserSettings(); Loading @@ -2223,7 +2241,7 @@ public class HdmiControlService extends SystemService { @Override public List<String> getAllowedCecSettingStringValues(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getAllowedStringValues(name); Loading @@ -2234,7 +2252,7 @@ public class HdmiControlService extends SystemService { @Override public int[] getAllowedCecSettingIntValues(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { List<Integer> allowedValues = Loading @@ -2247,7 +2265,7 @@ public class HdmiControlService extends SystemService { @Override public String getCecSettingStringValue(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getStringValue(name); Loading @@ -2258,7 +2276,7 @@ public class HdmiControlService extends SystemService { @Override public void setCecSettingStringValue(String name, String value) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.getHdmiCecConfig().setStringValue(name, value); Loading @@ -2269,7 +2287,7 @@ public class HdmiControlService extends SystemService { @Override public int getCecSettingIntValue(String name) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { return HdmiControlService.this.getHdmiCecConfig().getIntValue(name); Loading @@ -2280,7 +2298,7 @@ public class HdmiControlService extends SystemService { @Override public void setCecSettingIntValue(String name, int value) { enforceAccessPermission(); initBinderCall(); long token = Binder.clearCallingIdentity(); try { HdmiControlService.this.getHdmiCecConfig().setIntValue(name, value); Loading