Report specific exception type on decrypt with invalid session

bug: 22235465
Change-Id: Ic1e1a86529d4f2246b9768799aacde5cd1070d04
diff --git a/api/current.txt b/api/current.txt
index 340493e..40ba059 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15447,6 +15447,7 @@
     field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
     field public static final int ERROR_NO_KEY = 1; // 0x1
     field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+    field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
   }
 
   public static final class MediaCodec.CryptoInfo {
diff --git a/api/system-current.txt b/api/system-current.txt
index a64f7fe..ffb1ab5 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -16701,6 +16701,7 @@
     field public static final int ERROR_KEY_EXPIRED = 2; // 0x2
     field public static final int ERROR_NO_KEY = 1; // 0x1
     field public static final int ERROR_RESOURCE_BUSY = 3; // 0x3
+    field public static final int ERROR_SESSION_NOT_OPENED = 5; // 0x5
   }
 
   public static final class MediaCodec.CryptoInfo {
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index a79dd04..5f60891 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -2029,12 +2029,21 @@
          */
         public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
 
+        /**
+         * This indicates that decryption was attempted on a session that is
+         * not opened, which could be due to a failure to open the session,
+         * closing the session prematurely, or the session being reclaimed
+         * by the resource manager.
+         */
+        public static final int ERROR_SESSION_NOT_OPENED = 5;
+
         /** @hide */
         @IntDef({
             ERROR_NO_KEY,
             ERROR_KEY_EXPIRED,
             ERROR_RESOURCE_BUSY,
             ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+            ERROR_SESSION_NOT_OPENED,
         })
         @Retention(RetentionPolicy.SOURCE)
         public @interface CryptoErrorCode {}
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index ce7f7e5..218a117 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -64,6 +64,7 @@
     jint cryptoErrorKeyExpired;
     jint cryptoErrorResourceBusy;
     jint cryptoErrorInsufficientOutputProtection;
+    jint cryptoErrorSessionNotOpened;
 } gCryptoErrorCodes;
 
 static struct CodecActionCodes {
@@ -843,6 +844,9 @@
         case ERROR_DRM_INSUFFICIENT_OUTPUT_PROTECTION:
             err = gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection;
             break;
+        case ERROR_DRM_SESSION_NOT_OPENED:
+            err = gCryptoErrorCodes.cryptoErrorSessionNotOpened;
+            break;
         default:  /* Other negative DRM error codes go out as is. */
             break;
     }
@@ -1689,6 +1693,11 @@
     gCryptoErrorCodes.cryptoErrorInsufficientOutputProtection =
         env->GetStaticIntField(clazz.get(), field);
 
+    field = env->GetStaticFieldID(clazz.get(), "ERROR_SESSION_NOT_OPENED", "I");
+    CHECK(field != NULL);
+    gCryptoErrorCodes.cryptoErrorSessionNotOpened =
+        env->GetStaticIntField(clazz.get(), field);
+
     clazz.reset(env->FindClass("android/media/MediaCodec$CodecException"));
     CHECK(clazz.get() != NULL);
     field = env->GetStaticFieldID(clazz.get(), "ACTION_TRANSIENT", "I");