Loading media/java/android/media/MediaCas.java +79 −26 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.util.Log; import android.util.Singleton; Loading Loading @@ -360,14 +361,14 @@ public final class MediaCas implements AutoCloseable { @Override public void handleMessage(Message msg) { if (msg.what == MSG_CAS_EVENT) { mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, toBytes((ArrayList<Byte>) msg.obj)); byte[] data = (msg.obj == null) ? new byte[0] : (byte[]) msg.obj; mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, data); } else if (msg.what == MSG_CAS_SESSION_EVENT) { Bundle bundle = msg.getData(); byte[] sessionId = bundle.getByteArray(SESSION_KEY); mListener.onSessionEvent(MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, bundle.getByteArray(DATA_KEY)); byte[] data = bundle.getByteArray(DATA_KEY); mListener.onSessionEvent( MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, data); } else if (msg.what == MSG_CAS_STATUS_EVENT) { if ((msg.arg1 == PLUGIN_STATUS_SESSION_NUMBER_CHANGED) && (mTunerResourceManager != null)) { Loading Loading @@ -599,7 +600,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.setSessionPrivateData(mSessionId, data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setSessionPrivateData( Loading Loading @@ -628,7 +633,12 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { mICas.processEcm(mSessionId, data); try { mICas.processEcm( mSessionId, Arrays.copyOfRange(data, offset, length + offset)); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.processEcm( Loading Loading @@ -671,12 +681,14 @@ public final class MediaCas implements AutoCloseable { validateSessionInternalStates(); if (mICas != null) { try { if (data == null) { data = new byte[0]; } mICas.sendSessionEvent(mSessionId, event, arg, data); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } } } else { if (mICasHidl11 == null) { Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface"); throw new UnsupportedCasException("Send Session Event is not supported"); Loading @@ -690,6 +702,7 @@ public final class MediaCas implements AutoCloseable { cleanupAndRethrowIllegalState(); } } } /** * Get Session Id. Loading Loading @@ -1038,7 +1051,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.setPrivateData(data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setPrivateData(toByteArray(data, 0, data.length))); Loading Loading @@ -1126,7 +1143,21 @@ public final class MediaCas implements AutoCloseable { int sessionResourceHandle = getSessionResourceHandle(); try { if (mICasHidl != null) { if (mICas != null) { try { byte[] sessionId = mICas.openSessionDefault(); Session session = createFromSessionId(sessionId); Log.d(TAG, "Write Stats Log for succeed to Open Session."); FrameworkStatsLog.write( FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId, FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED); return session; } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else if (mICasHidl != null) { OpenSessionCallback cb = new OpenSessionCallback(); mICasHidl.openSession(cb); MediaCasException.throwExceptionIfNeeded(cb.mStatus); Loading Loading @@ -1183,7 +1214,7 @@ public final class MediaCas implements AutoCloseable { mCasSystemId, FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED); return session; } catch (RemoteException e) { } catch (ServiceSpecificException | RemoteException e) { cleanupAndRethrowIllegalState(); } } Loading Loading @@ -1229,7 +1260,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.processEmm(Arrays.copyOfRange(data, offset, length)); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.processEmm(toByteArray(data, offset, length))); Loading Loading @@ -1272,7 +1307,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { if (data == null) { data = new byte[0]; } mICas.sendEvent(event, arg, data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.sendEvent(event, arg, toByteArray(data))); Loading @@ -1298,7 +1340,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.provision(provisionString); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded(mICasHidl.provision(provisionString)); } Loading @@ -1323,7 +1369,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { if (refreshData == null) { refreshData = new byte[0]; } mICas.refreshEntitlements(refreshType, refreshData); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.refreshEntitlements(refreshType, toByteArray(refreshData))); Loading media/java/android/media/MediaDescrambler.java +31 −84 Original line number Diff line number Diff line Loading @@ -17,24 +17,15 @@ package android.media; import android.annotation.NonNull; import android.hardware.cas.DestinationBuffer; import android.hardware.cas.IDescrambler; import android.hardware.cas.ScramblingControl; import android.hardware.cas.SharedBuffer; import android.hardware.cas.SubSample; import android.hardware.cas.V1_0.IDescramblerBase; import android.hardware.common.Ashmem; import android.hardware.common.NativeHandle; import android.media.MediaCasException.UnsupportedCasException; import android.os.IHwBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.SharedMemory; import android.system.ErrnoException; import android.util.Log; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; Loading @@ -52,6 +43,7 @@ import java.util.ArrayList; public final class MediaDescrambler implements AutoCloseable { private static final String TAG = "MediaDescrambler"; private DescramblerWrapper mIDescrambler; private boolean mIsAidlHal; private interface DescramblerWrapper { Loading @@ -68,50 +60,18 @@ public final class MediaDescrambler implements AutoCloseable { void setMediaCasSession(byte[] sessionId) throws RemoteException; void release() throws RemoteException; } ; private long getSubsampleInfo( int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData, SubSample[] subSamples) { long totalSize = 0; for (int i = 0; i < numSubSamples; i++) { totalSize += numBytesOfClearData[i]; subSamples[i].numBytesOfClearData = numBytesOfClearData[i]; totalSize += numBytesOfEncryptedData[i]; subSamples[i].numBytesOfEncryptedData = numBytesOfEncryptedData[i]; } return totalSize; } private ParcelFileDescriptor createSharedMemory(ByteBuffer buffer, String name) throws RemoteException { byte[] source = buffer.array(); if (source.length == 0) { return null; } ParcelFileDescriptor fd = null; try { SharedMemory ashmem = SharedMemory.create(name == null ? "" : name, source.length); ByteBuffer ptr = ashmem.mapReadWrite(); ptr.put(buffer); ashmem.unmap(ptr); fd = ashmem.getFdDup(); return fd; } catch (ErrnoException | IOException e) { throw new RemoteException(e); } } }; private class AidlDescrambler implements DescramblerWrapper { IDescrambler mAidlDescrambler; AidlDescrambler(IDescrambler aidlDescrambler) { AidlDescrambler(IDescrambler aidlDescrambler) throws Exception { if (aidlDescrambler != null) { mAidlDescrambler = aidlDescrambler; } else { throw new Exception("Descrambler could not be created"); } } @Override Loading @@ -125,47 +85,17 @@ public final class MediaDescrambler implements AutoCloseable { @NonNull ByteBuffer dst, @NonNull MediaCodec.CryptoInfo cryptoInfo) throws RemoteException { SubSample[] subSamples = new SubSample[cryptoInfo.numSubSamples]; long totalLength = getSubsampleInfo( cryptoInfo.numSubSamples, cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData, subSamples); SharedBuffer srcBuffer = new SharedBuffer(); DestinationBuffer dstBuffer; srcBuffer.heapBase = new Ashmem(); srcBuffer.heapBase.fd = createSharedMemory(src, "Descrambler Source Buffer"); srcBuffer.heapBase.size = src.array().length; if (dst == null) { dstBuffer = DestinationBuffer.nonsecureMemory(srcBuffer); } else { ParcelFileDescriptor pfd = createSharedMemory(dst, "Descrambler Destination Buffer"); NativeHandle nh = new NativeHandle(); nh.fds = new ParcelFileDescriptor[] {pfd}; nh.ints = new int[] {1}; // Mark 1 since source buffer also uses it? dstBuffer = DestinationBuffer.secureMemory(nh); } @ScramblingControl int control = cryptoInfo.key[0]; return mAidlDescrambler.descramble( (byte) control, subSamples, srcBuffer, src.position(), dstBuffer, dst.position()); throw new RemoteException("Not supported"); } @Override public boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException { return mAidlDescrambler.requiresSecureDecoderComponent(mime); throw new RemoteException("Not supported"); } @Override public void setMediaCasSession(byte[] sessionId) throws RemoteException { mAidlDescrambler.setMediaCasSession(sessionId); throw new RemoteException("Not supported"); } @Override Loading @@ -178,9 +108,13 @@ public final class MediaDescrambler implements AutoCloseable { IDescramblerBase mHidlDescrambler; HidlDescrambler(IDescramblerBase hidlDescrambler) { HidlDescrambler(IDescramblerBase hidlDescrambler) throws Exception { if (hidlDescrambler != null) { mHidlDescrambler = hidlDescrambler; native_setup(hidlDescrambler.asBinder()); } else { throw new Exception("Descrambler could not be created"); } } @Override Loading Loading @@ -267,10 +201,14 @@ public final class MediaDescrambler implements AutoCloseable { if (MediaCas.getService() != null) { mIDescrambler = new AidlDescrambler(MediaCas.getService().createDescrambler(CA_system_id)); mIsAidlHal = true; } else if (MediaCas.getServiceHidl() != null) { mIDescrambler = new HidlDescrambler( MediaCas.getServiceHidl().createDescrambler(CA_system_id)); mIsAidlHal = false; } else { throw new Exception("No CAS service found!"); } } catch(Exception e) { Log.e(TAG, "Failed to create descrambler: " + e); Loading @@ -282,6 +220,15 @@ public final class MediaDescrambler implements AutoCloseable { } } /** * Check if the underlying HAL is AIDL. Used only for CTS. * * @hide */ public boolean isAidlHal() { return mIsAidlHal; } IHwBinder getBinder() { validateInternalStates(); Loading Loading
media/java/android/media/MediaCas.java +79 −26 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceSpecificException; import android.util.Log; import android.util.Singleton; Loading Loading @@ -360,14 +361,14 @@ public final class MediaCas implements AutoCloseable { @Override public void handleMessage(Message msg) { if (msg.what == MSG_CAS_EVENT) { mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, toBytes((ArrayList<Byte>) msg.obj)); byte[] data = (msg.obj == null) ? new byte[0] : (byte[]) msg.obj; mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2, data); } else if (msg.what == MSG_CAS_SESSION_EVENT) { Bundle bundle = msg.getData(); byte[] sessionId = bundle.getByteArray(SESSION_KEY); mListener.onSessionEvent(MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, bundle.getByteArray(DATA_KEY)); byte[] data = bundle.getByteArray(DATA_KEY); mListener.onSessionEvent( MediaCas.this, createFromSessionId(sessionId), msg.arg1, msg.arg2, data); } else if (msg.what == MSG_CAS_STATUS_EVENT) { if ((msg.arg1 == PLUGIN_STATUS_SESSION_NUMBER_CHANGED) && (mTunerResourceManager != null)) { Loading Loading @@ -599,7 +600,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.setSessionPrivateData(mSessionId, data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setSessionPrivateData( Loading Loading @@ -628,7 +633,12 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { mICas.processEcm(mSessionId, data); try { mICas.processEcm( mSessionId, Arrays.copyOfRange(data, offset, length + offset)); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.processEcm( Loading Loading @@ -671,12 +681,14 @@ public final class MediaCas implements AutoCloseable { validateSessionInternalStates(); if (mICas != null) { try { if (data == null) { data = new byte[0]; } mICas.sendSessionEvent(mSessionId, event, arg, data); } catch (RemoteException e) { cleanupAndRethrowIllegalState(); } } } else { if (mICasHidl11 == null) { Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface"); throw new UnsupportedCasException("Send Session Event is not supported"); Loading @@ -690,6 +702,7 @@ public final class MediaCas implements AutoCloseable { cleanupAndRethrowIllegalState(); } } } /** * Get Session Id. Loading Loading @@ -1038,7 +1051,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.setPrivateData(data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setPrivateData(toByteArray(data, 0, data.length))); Loading Loading @@ -1126,7 +1143,21 @@ public final class MediaCas implements AutoCloseable { int sessionResourceHandle = getSessionResourceHandle(); try { if (mICasHidl != null) { if (mICas != null) { try { byte[] sessionId = mICas.openSessionDefault(); Session session = createFromSessionId(sessionId); Log.d(TAG, "Write Stats Log for succeed to Open Session."); FrameworkStatsLog.write( FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId, FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED); return session; } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else if (mICasHidl != null) { OpenSessionCallback cb = new OpenSessionCallback(); mICasHidl.openSession(cb); MediaCasException.throwExceptionIfNeeded(cb.mStatus); Loading Loading @@ -1183,7 +1214,7 @@ public final class MediaCas implements AutoCloseable { mCasSystemId, FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED); return session; } catch (RemoteException e) { } catch (ServiceSpecificException | RemoteException e) { cleanupAndRethrowIllegalState(); } } Loading Loading @@ -1229,7 +1260,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.processEmm(Arrays.copyOfRange(data, offset, length)); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.processEmm(toByteArray(data, offset, length))); Loading Loading @@ -1272,7 +1307,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { if (data == null) { data = new byte[0]; } mICas.sendEvent(event, arg, data); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.sendEvent(event, arg, toByteArray(data))); Loading @@ -1298,7 +1340,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { mICas.provision(provisionString); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded(mICasHidl.provision(provisionString)); } Loading @@ -1323,7 +1369,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { try { if (refreshData == null) { refreshData = new byte[0]; } mICas.refreshEntitlements(refreshType, refreshData); } catch (ServiceSpecificException se) { MediaCasException.throwExceptionIfNeeded(se.errorCode); } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.refreshEntitlements(refreshType, toByteArray(refreshData))); Loading
media/java/android/media/MediaDescrambler.java +31 −84 Original line number Diff line number Diff line Loading @@ -17,24 +17,15 @@ package android.media; import android.annotation.NonNull; import android.hardware.cas.DestinationBuffer; import android.hardware.cas.IDescrambler; import android.hardware.cas.ScramblingControl; import android.hardware.cas.SharedBuffer; import android.hardware.cas.SubSample; import android.hardware.cas.V1_0.IDescramblerBase; import android.hardware.common.Ashmem; import android.hardware.common.NativeHandle; import android.media.MediaCasException.UnsupportedCasException; import android.os.IHwBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.SharedMemory; import android.system.ErrnoException; import android.util.Log; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; Loading @@ -52,6 +43,7 @@ import java.util.ArrayList; public final class MediaDescrambler implements AutoCloseable { private static final String TAG = "MediaDescrambler"; private DescramblerWrapper mIDescrambler; private boolean mIsAidlHal; private interface DescramblerWrapper { Loading @@ -68,50 +60,18 @@ public final class MediaDescrambler implements AutoCloseable { void setMediaCasSession(byte[] sessionId) throws RemoteException; void release() throws RemoteException; } ; private long getSubsampleInfo( int numSubSamples, int[] numBytesOfClearData, int[] numBytesOfEncryptedData, SubSample[] subSamples) { long totalSize = 0; for (int i = 0; i < numSubSamples; i++) { totalSize += numBytesOfClearData[i]; subSamples[i].numBytesOfClearData = numBytesOfClearData[i]; totalSize += numBytesOfEncryptedData[i]; subSamples[i].numBytesOfEncryptedData = numBytesOfEncryptedData[i]; } return totalSize; } private ParcelFileDescriptor createSharedMemory(ByteBuffer buffer, String name) throws RemoteException { byte[] source = buffer.array(); if (source.length == 0) { return null; } ParcelFileDescriptor fd = null; try { SharedMemory ashmem = SharedMemory.create(name == null ? "" : name, source.length); ByteBuffer ptr = ashmem.mapReadWrite(); ptr.put(buffer); ashmem.unmap(ptr); fd = ashmem.getFdDup(); return fd; } catch (ErrnoException | IOException e) { throw new RemoteException(e); } } }; private class AidlDescrambler implements DescramblerWrapper { IDescrambler mAidlDescrambler; AidlDescrambler(IDescrambler aidlDescrambler) { AidlDescrambler(IDescrambler aidlDescrambler) throws Exception { if (aidlDescrambler != null) { mAidlDescrambler = aidlDescrambler; } else { throw new Exception("Descrambler could not be created"); } } @Override Loading @@ -125,47 +85,17 @@ public final class MediaDescrambler implements AutoCloseable { @NonNull ByteBuffer dst, @NonNull MediaCodec.CryptoInfo cryptoInfo) throws RemoteException { SubSample[] subSamples = new SubSample[cryptoInfo.numSubSamples]; long totalLength = getSubsampleInfo( cryptoInfo.numSubSamples, cryptoInfo.numBytesOfClearData, cryptoInfo.numBytesOfEncryptedData, subSamples); SharedBuffer srcBuffer = new SharedBuffer(); DestinationBuffer dstBuffer; srcBuffer.heapBase = new Ashmem(); srcBuffer.heapBase.fd = createSharedMemory(src, "Descrambler Source Buffer"); srcBuffer.heapBase.size = src.array().length; if (dst == null) { dstBuffer = DestinationBuffer.nonsecureMemory(srcBuffer); } else { ParcelFileDescriptor pfd = createSharedMemory(dst, "Descrambler Destination Buffer"); NativeHandle nh = new NativeHandle(); nh.fds = new ParcelFileDescriptor[] {pfd}; nh.ints = new int[] {1}; // Mark 1 since source buffer also uses it? dstBuffer = DestinationBuffer.secureMemory(nh); } @ScramblingControl int control = cryptoInfo.key[0]; return mAidlDescrambler.descramble( (byte) control, subSamples, srcBuffer, src.position(), dstBuffer, dst.position()); throw new RemoteException("Not supported"); } @Override public boolean requiresSecureDecoderComponent(@NonNull String mime) throws RemoteException { return mAidlDescrambler.requiresSecureDecoderComponent(mime); throw new RemoteException("Not supported"); } @Override public void setMediaCasSession(byte[] sessionId) throws RemoteException { mAidlDescrambler.setMediaCasSession(sessionId); throw new RemoteException("Not supported"); } @Override Loading @@ -178,9 +108,13 @@ public final class MediaDescrambler implements AutoCloseable { IDescramblerBase mHidlDescrambler; HidlDescrambler(IDescramblerBase hidlDescrambler) { HidlDescrambler(IDescramblerBase hidlDescrambler) throws Exception { if (hidlDescrambler != null) { mHidlDescrambler = hidlDescrambler; native_setup(hidlDescrambler.asBinder()); } else { throw new Exception("Descrambler could not be created"); } } @Override Loading Loading @@ -267,10 +201,14 @@ public final class MediaDescrambler implements AutoCloseable { if (MediaCas.getService() != null) { mIDescrambler = new AidlDescrambler(MediaCas.getService().createDescrambler(CA_system_id)); mIsAidlHal = true; } else if (MediaCas.getServiceHidl() != null) { mIDescrambler = new HidlDescrambler( MediaCas.getServiceHidl().createDescrambler(CA_system_id)); mIsAidlHal = false; } else { throw new Exception("No CAS service found!"); } } catch(Exception e) { Log.e(TAG, "Failed to create descrambler: " + e); Loading @@ -282,6 +220,15 @@ public final class MediaDescrambler implements AutoCloseable { } } /** * Check if the underlying HAL is AIDL. Used only for CTS. * * @hide */ public boolean isAidlHal() { return mIsAidlHal; } IHwBinder getBinder() { validateInternalStates(); Loading