title: Spotify Web Player crashes system WebView due to MediaDrm exception
body: <p>I am working on an android app that uses the Spotify Web Playback SDK. This works fine for about 99% of the time, but that 1% is where my app will crash due to Spotify. Currently I receive the following stack trace:</p>
  <pre><code>2022-02-02 11:20:39.931 13285-13285/app.***.musicplayer E/AndroidRuntime: FATAL EXCEPTION: main
      Process: app.***.musicplayer, PID: 13285
      java.lang.NullPointerException: Attempt to read from field 'byte[] ES.a' on a null object reference
          at GS.b(Unknown Source:2)
          at zS.onKeyStatusChange(Unknown Source:10)
          at android.media.MediaDrm.lambda$createOnKeyStatusChangeListener$1$MediaDrm(MediaDrm.java:809)
          at android.media.-$$Lambda$MediaDrm$_FHBF1q3qSxz22Mhv8jmgjN4xt0.accept(Unknown Source:6)
          at android.media.MediaDrm.lambda$postEventFromNative$4(MediaDrm.java:920)
          at android.media.-$$Lambda$MediaDrm$UPVWCanGo24eu9-1S_t6PvJ1Zno.run(Unknown Source:18)
          at android.os.Handler.handleCallback(Handler.java:938)
          at android.os.Handler.dispatchMessage(Handler.java:99)
          at android.os.Looper.loop(Looper.java:223)
          at android.app.ActivityThread.main(ActivityThread.java:7656)
          at java.lang.reflect.Method.invoke(Native Method)
          at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
  2022-02-02 12:23:43.223 26211-26249/? E/Finsky:instant_app_inst: [50634] EnabledStatusSyncService.d(47): Failed updateUserPrefs: Account=Account {name=***@***.app, type=com.google}, EnableInstantApps=true
  </code></pre>
  <p>From what I can figure out, Spotify attempts to use the system WebView's Media DRM for managing Key Sessions. At some point, Spotify attempts to do something which causes the WebView to throw this <code>NullPointerException</code> which in-turn crashes my app.</p>
  <p><strong>Is there ANY way I can somehow catch this exception and recover to prevent my app from crashing?</strong></p>
  <p>I've been looking at maybe trying to find a third-party WebView, but I'd hate to have to bloat my app because of something like this.</p>
  <p>I don't know if this is in-fact the offending code, but it was the only thing in the Spotify SDK that I could find that referenced a <code>keyStatusChangeListener</code>:</p>
  <pre class="lang-js prettyprint-override"><code>t.prototype.destroySessions = function () {
      for (var e = [], t = 0, r = this._keySessions; t &lt; r.length; t++) {
          var n = r[t];
          try {
              var i = n.keySession;
              if (!i) continue;
              n.onMessageListener &amp;&amp; i.removeEventListener(s.Event.KEY_SESSION_MESSAGE, n.onMessageListener), n.onKeyStatusChangeListener &amp;&amp; i.removeEventListener(s.Event.KEY_SESSION_STATUSES_CHANGE, n.onKeyStatusChangeListener);
              var o = Promise.resolve(i.close()).catch(function (e) {
                  E.warn(&quot;Failed to close KeySession&quot;, e);
              });
              e.push(o), n.keySession = null, n.onMessageListener = null, n.onKeyStatusChangeListener = null, E.info(&quot;Closed KeySession&quot;);
          } catch (e) {
              E.warn(&quot;Failed to close KeySession&quot;, e);
          }
      }
      return this._keySessions = [], Promise.all(e);
  }
  </code></pre>
  <p>They put a try...catch around it to handle errors, but it's not like they can do anything when the WebView itself has no safety checks:</p>
  <blockquote>
  <p>MediaDrm.java from the Android code base</p>
  </blockquote>
  <pre class="lang-java prettyprint-override"><code>private Consumer&lt;ListenerArgs&gt; createOnKeyStatusChangeListener(
          OnKeyStatusChangeListener listener) {
      return args -&gt; {
          byte[] sessionId = args.sessionId;
          if (sessionId.length &gt; 0) {
              List&lt;KeyStatus&gt; keyStatusList = args.keyStatusList;
              boolean hasNewUsableKey = args.hasNewUsableKey;
  
              Log.i(TAG, &quot;Drm key status changed&quot;);
              listener.onKeyStatusChange(this, sessionId, keyStatusList, hasNewUsableKey);
          }
      };
  }
  </code></pre>