diff --git a/media/java/android/media/MediaCas.java b/media/java/android/media/MediaCas.java index 015602e95533f..0704da4fb63d8 100644 --- a/media/java/android/media/MediaCas.java +++ b/media/java/android/media/MediaCas.java @@ -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; @@ -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) 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)) { @@ -599,7 +600,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.setSessionPrivateData(mSessionId, data); + try { + mICas.setSessionPrivateData(mSessionId, data); + } catch (ServiceSpecificException se) { + MediaCasException.throwExceptionIfNeeded(se.errorCode); + } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setSessionPrivateData( @@ -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( @@ -671,23 +681,26 @@ 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"); + } - 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"); - } - - try { - MediaCasException.throwExceptionIfNeeded( - mICasHidl11.sendSessionEvent( - toByteArray(mSessionId), event, arg, toByteArray(data))); - } catch (RemoteException e) { - cleanupAndRethrowIllegalState(); + try { + MediaCasException.throwExceptionIfNeeded( + mICasHidl11.sendSessionEvent( + toByteArray(mSessionId), event, arg, toByteArray(data))); + } catch (RemoteException e) { + cleanupAndRethrowIllegalState(); + } } } @@ -1038,7 +1051,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.setPrivateData(data); + try { + mICas.setPrivateData(data); + } catch (ServiceSpecificException se) { + MediaCasException.throwExceptionIfNeeded(se.errorCode); + } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.setPrivateData(toByteArray(data, 0, data.length))); @@ -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); @@ -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(); } } @@ -1229,7 +1260,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.processEmm(Arrays.copyOfRange(data, offset, length)); + try { + mICas.processEmm(Arrays.copyOfRange(data, offset, length)); + } catch (ServiceSpecificException se) { + MediaCasException.throwExceptionIfNeeded(se.errorCode); + } } else { MediaCasException.throwExceptionIfNeeded( mICasHidl.processEmm(toByteArray(data, offset, length))); @@ -1272,7 +1307,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.sendEvent(event, arg, data); + 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))); @@ -1298,7 +1340,11 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.provision(provisionString); + try { + mICas.provision(provisionString); + } catch (ServiceSpecificException se) { + MediaCasException.throwExceptionIfNeeded(se.errorCode); + } } else { MediaCasException.throwExceptionIfNeeded(mICasHidl.provision(provisionString)); } @@ -1323,7 +1369,14 @@ public final class MediaCas implements AutoCloseable { try { if (mICas != null) { - mICas.refreshEntitlements(refreshType, refreshData); + 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))); diff --git a/media/java/android/media/MediaDescrambler.java b/media/java/android/media/MediaDescrambler.java index b4bdf93db3abe..15dee8516f0c7 100644 --- a/media/java/android/media/MediaDescrambler.java +++ b/media/java/android/media/MediaDescrambler.java @@ -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; @@ -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 { @@ -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) { - mAidlDescrambler = aidlDescrambler; + AidlDescrambler(IDescrambler aidlDescrambler) throws Exception { + if (aidlDescrambler != null) { + mAidlDescrambler = aidlDescrambler; + } else { + throw new Exception("Descrambler could not be created"); + } } @Override @@ -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 @@ -178,9 +108,13 @@ public final class MediaDescrambler implements AutoCloseable { IDescramblerBase mHidlDescrambler; - HidlDescrambler(IDescramblerBase hidlDescrambler) { - mHidlDescrambler = hidlDescrambler; - native_setup(hidlDescrambler.asBinder()); + HidlDescrambler(IDescramblerBase hidlDescrambler) throws Exception { + if (hidlDescrambler != null) { + mHidlDescrambler = hidlDescrambler; + native_setup(hidlDescrambler.asBinder()); + } else { + throw new Exception("Descrambler could not be created"); + } } @Override @@ -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); @@ -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();