Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02937121 authored by Robert Shih's avatar Robert Shih
Browse files

MediaDrm: implement PlaybackComponent

Also make PlaybackComponent available to tests

Bug: 159337195
Bug: 168341163
Test: GtsMediaTestCases MediaDrmTest#testSetPlaybackId
Change-Id: I9bba9340f77a5baddb7e946f0e0e84033350727c
parent 205f7a9f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -1088,6 +1088,11 @@ package android.media {
    method public void forceResourceLost();
  }

  public final class MediaCodec implements android.media.metrics.PlaybackComponent {
    method public String getPlaybackId();
    method public void setPlaybackId(@NonNull String);
  }

  public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
    ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size);
    ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size);
@@ -1096,6 +1101,10 @@ package android.media {
    method public int getMaxMacroBlocks();
  }

  public final class MediaDrm implements java.lang.AutoCloseable {
    method @Nullable public android.media.metrics.PlaybackComponent getPlaybackComponent(@NonNull byte[]);
  }

  public final class MediaRoute2Info implements android.os.Parcelable {
    method @NonNull public String getOriginalId();
  }
@@ -1158,6 +1167,15 @@ package android.media.audiopolicy {

}

package android.media.metrics {

  public interface PlaybackComponent {
    method @NonNull public String getPlaybackId();
    method public void setPlaybackId(@NonNull String);
  }

}

package android.media.tv {

  public final class TvInputManager {
+67 −4
Original line number Diff line number Diff line
@@ -21,8 +21,10 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StringDef;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.media.metrics.PlaybackComponent;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
@@ -35,8 +37,8 @@ import dalvik.system.CloseGuard;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.ref.WeakReference;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
@@ -49,7 +51,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import java.util.function.Function;


/**
 * MediaDrm can be used to obtain keys for decrypting protected media streams, in
 * conjunction with {@link android.media.MediaCrypto}.  The MediaDrm APIs
@@ -963,14 +964,30 @@ public final class MediaDrm implements AutoCloseable {
     * a session
     */
    @NonNull
    public native byte[] openSession(@SecurityLevel int level) throws
    public byte[] openSession(@SecurityLevel int level) throws
            NotProvisionedException, ResourceBusyException {
        byte[] sessionId = openSessionNative(level);
        mPlaybackComponentMap.put(ByteBuffer.wrap(sessionId), new PlaybackComponentImpl(sessionId));
        return sessionId;
    }

    @NonNull
    private native byte[] openSessionNative(int level) throws
            NotProvisionedException, ResourceBusyException;

    /**
     * Close a session on the MediaDrm object that was previously opened
     * with {@link #openSession}.
     */
    public native void closeSession(@NonNull byte[] sessionId);
    public void closeSession(@NonNull byte[] sessionId) {
        closeSessionNative(sessionId);
        mPlaybackComponentMap.remove(ByteBuffer.wrap(sessionId));
    }

    private native void closeSessionNative(@NonNull byte[] sessionId);

    private final Map<ByteBuffer, PlaybackComponent> mPlaybackComponentMap
            = new ConcurrentHashMap<>();

    /**
     * This key request type species that the keys will be for online use, they will
@@ -2055,6 +2072,7 @@ public final class MediaDrm implements AutoCloseable {
        mCloseGuard.close();
        if (mClosed.compareAndSet(false, true)) {
            native_release();
            mPlaybackComponentMap.clear();
        }
    }

@@ -2429,4 +2447,49 @@ public final class MediaDrm implements AutoCloseable {
        public static final String EVENT_SESSION_RECLAIMED_COUNT
            = "drm.mediadrm.event.SESSION_RECLAIMED.count";
    }

    /**
     * Obtain a {@link PlaybackComponent} associated with a DRM session.
     * Call {@link PlaybackComponent#setPlaybackId(String)} on the returned object
     * to associate a playback session with the DRM session.
     *
     * @param sessionId a DRM session ID obtained from {@link #openSession()}
     * @return a {@link PlaybackComponent} associated with the session,
     * or {@code null} if the session is closed or does not exist.
     * @see PlaybackComponent
     * @hide
     */
    @TestApi
    @Nullable
    public PlaybackComponent getPlaybackComponent(@NonNull byte[] sessionId) {
        if (sessionId == null) {
            throw new IllegalArgumentException("sessionId is null");
        }
        return mPlaybackComponentMap.get(ByteBuffer.wrap(sessionId));
    }

    private native void setPlaybackId(byte[] sessionId, String playbackId);

    private final class PlaybackComponentImpl implements PlaybackComponent {
        private final byte[] mSessionId;
        private String mPlaybackId = "";

        public PlaybackComponentImpl(byte[] sessionId) {
            mSessionId = sessionId;
        }

        @Override
        public void setPlaybackId(@NonNull String playbackId) {
            if (playbackId == null) {
                throw new IllegalArgumentException("playbackId is null");
            }
            MediaDrm.this.setPlaybackId(mSessionId, playbackId);
            mPlaybackId = playbackId;
        }

        @Override
        @NonNull public String getPlaybackId() {
            return mPlaybackId;
        }
    }
}
+2 −0
Original line number Diff line number Diff line
@@ -17,11 +17,13 @@
package android.media.metrics;

import android.annotation.NonNull;
import android.annotation.TestApi;

/**
 * Interface for playback related components used by playback metrics.
 * @hide
 */
@TestApi
public interface PlaybackComponent {

    /**
+23 −2
Original line number Diff line number Diff line
@@ -1978,6 +1978,24 @@ static jboolean android_media_MediaDrm_requiresSecureDecoder(
    return drm->requiresSecureDecoder(mimeType.c_str(), securityLevel);
}

static void android_media_MediaDrm_setPlaybackId(
        JNIEnv *env, jobject thiz, jbyteArray jsessionId,
        jstring jplaybackId) {
    sp<IDrm> drm = GetDrm(env, thiz);
    if (!CheckSession(env, drm, jsessionId)) {
        return;
    }

    Vector<uint8_t> sessionId(JByteArrayToVector(env, jsessionId));

    String8 playbackId;
    if (jplaybackId != NULL) {
        playbackId = JStringToString8(env, jplaybackId);
    }
    status_t err = drm->setPlaybackId(sessionId, playbackId.c_str());
    throwExceptionAsNecessary(env, err, "Failed to set playbackId");
}

static const JNINativeMethod gMethods[] = {
    { "native_release", "()V", (void *)android_media_MediaDrm_native_release },

@@ -1992,10 +2010,10 @@ static const JNINativeMethod gMethods[] = {
    { "isCryptoSchemeSupportedNative", "([BLjava/lang/String;I)Z",
      (void *)android_media_MediaDrm_isCryptoSchemeSupportedNative },

    { "openSession", "(I)[B",
    { "openSessionNative", "(I)[B",
      (void *)android_media_MediaDrm_openSession },

    { "closeSession", "([B)V",
    { "closeSessionNative", "([B)V",
      (void *)android_media_MediaDrm_closeSession },

    { "getKeyRequest", "([B[BLjava/lang/String;ILjava/util/HashMap;)"
@@ -2102,6 +2120,9 @@ static const JNINativeMethod gMethods[] = {

    { "requiresSecureDecoder", "(Ljava/lang/String;I)Z",
      (void *)android_media_MediaDrm_requiresSecureDecoder },

    { "setPlaybackId", "([BLjava/lang/String;)V",
      (void *)android_media_MediaDrm_setPlaybackId },
};

int register_android_media_Drm(JNIEnv *env) {