MediaDrm: API to retrieve LogMessages
Bug: 162255728 Test: cts/gts MediaDrmTest Change-Id: Icba4945a75eb00b737d65572b40cf2035504ca08
This commit is contained in:
@@ -21591,6 +21591,7 @@ package android.media {
|
||||
method @android.media.MediaDrm.HdcpLevel public int getConnectedHdcpLevel();
|
||||
method public android.media.MediaDrm.CryptoSession getCryptoSession(@NonNull byte[], @NonNull String, @NonNull String);
|
||||
method @NonNull public android.media.MediaDrm.KeyRequest getKeyRequest(@NonNull byte[], @Nullable byte[], @Nullable String, int, @Nullable java.util.HashMap<java.lang.String,java.lang.String>) throws android.media.NotProvisionedException;
|
||||
method @NonNull public java.util.List<android.media.MediaDrm.LogMessage> getLogMessages();
|
||||
method @android.media.MediaDrm.HdcpLevel public int getMaxHdcpLevel();
|
||||
method public static int getMaxSecurityLevel();
|
||||
method public int getMaxSessionCount();
|
||||
@@ -21699,6 +21700,12 @@ package android.media {
|
||||
field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5
|
||||
}
|
||||
|
||||
public static class MediaDrm.LogMessage {
|
||||
field @NonNull public final String message;
|
||||
field public final int priority;
|
||||
field public final long timestampMillis;
|
||||
}
|
||||
|
||||
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
|
||||
method @NonNull public String getDiagnosticInfo();
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -2493,4 +2494,80 @@ public final class MediaDrm implements AutoCloseable {
|
||||
return mPlaybackId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns recent {@link LogMessage LogMessages} associated with this {@link MediaDrm}
|
||||
* instance.
|
||||
*/
|
||||
@NonNull
|
||||
public native List<LogMessage> getLogMessages();
|
||||
|
||||
/**
|
||||
* A {@link LogMessage} records an event in the {@link MediaDrm} framework
|
||||
* or vendor plugin.
|
||||
*/
|
||||
public static class LogMessage {
|
||||
|
||||
/**
|
||||
* Timing of the recorded event measured in milliseconds since the Epoch,
|
||||
* 1970-01-01 00:00:00 +0000 (UTC).
|
||||
*/
|
||||
public final long timestampMillis;
|
||||
|
||||
/**
|
||||
* Priority of the recorded event.
|
||||
* <p>
|
||||
* Possible priority constants are defined in {@link Log}, e.g.:
|
||||
* <ul>
|
||||
* <li>{@link Log#ASSERT}</li>
|
||||
* <li>{@link Log#ERROR}</li>
|
||||
* <li>{@link Log#WARN}</li>
|
||||
* <li>{@link Log#INFO}</li>
|
||||
* <li>{@link Log#DEBUG}</li>
|
||||
* <li>{@link Log#VERBOSE}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Log.Level
|
||||
public final int priority;
|
||||
|
||||
/**
|
||||
* Description of the recorded event.
|
||||
*/
|
||||
@NonNull
|
||||
public final String message;
|
||||
|
||||
private LogMessage(long timestampMillis, int priority, String message) {
|
||||
this.timestampMillis = timestampMillis;
|
||||
if (priority < Log.VERBOSE || priority > Log.ASSERT) {
|
||||
throw new IllegalArgumentException("invalid log priority " + priority);
|
||||
}
|
||||
this.priority = priority;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
private char logPriorityChar() {
|
||||
switch (priority) {
|
||||
case Log.VERBOSE:
|
||||
return 'V';
|
||||
case Log.DEBUG:
|
||||
return 'D';
|
||||
case Log.INFO:
|
||||
return 'I';
|
||||
case Log.WARN:
|
||||
return 'W';
|
||||
case Log.ERROR:
|
||||
return 'E';
|
||||
case Log.ASSERT:
|
||||
return 'F';
|
||||
default:
|
||||
}
|
||||
return 'U';
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("LogMessage{%s %c %s}",
|
||||
Instant.ofEpochMilli(timestampMillis), logPriorityChar(), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ cc_library_shared {
|
||||
"android.hardware.cas@1.0",
|
||||
"android.hardware.cas.native@1.0",
|
||||
"android.hardware.drm@1.3",
|
||||
"android.hardware.drm@1.4",
|
||||
"android.hidl.memory@1.0",
|
||||
"android.hidl.token@1.0-utils",
|
||||
],
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <mediadrm/DrmUtils.h>
|
||||
#include <mediadrm/IDrmMetricsConsumer.h>
|
||||
#include <mediadrm/IDrm.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
using ::android::os::PersistableBundle;
|
||||
namespace drm = ::android::hardware::drm;
|
||||
@@ -187,6 +188,11 @@ struct KeyStatusFields {
|
||||
jclass classId;
|
||||
};
|
||||
|
||||
struct LogMessageFields {
|
||||
jmethodID init;
|
||||
jclass classId;
|
||||
};
|
||||
|
||||
struct fields_t {
|
||||
jfieldID context;
|
||||
jmethodID post_event;
|
||||
@@ -208,6 +214,7 @@ struct fields_t {
|
||||
jmethodID createFromParcelId;
|
||||
jclass parcelCreatorClassId;
|
||||
KeyStatusFields keyStatus;
|
||||
LogMessageFields logMessage;
|
||||
};
|
||||
|
||||
static fields_t gFields;
|
||||
@@ -224,6 +231,19 @@ jbyteArray hidlVectorToJByteArray(const hardware::hidl_vec<uint8_t> &vector) {
|
||||
return result;
|
||||
}
|
||||
|
||||
jobject hidlLogMessagesToJavaList(JNIEnv *env, const Vector<drm::V1_4::LogMessage> &logs) {
|
||||
jclass clazz = gFields.arraylistClassId;
|
||||
jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
|
||||
clazz = gFields.logMessage.classId;
|
||||
for (auto log: logs) {
|
||||
jobject jLog = env->NewObject(clazz, gFields.logMessage.init,
|
||||
static_cast<jlong>(log.timeMs),
|
||||
static_cast<jint>(log.priority),
|
||||
env->NewStringUTF(log.message.c_str()));
|
||||
env->CallBooleanMethod(arrayList, gFields.arraylist.add, jLog);
|
||||
}
|
||||
return arrayList;
|
||||
}
|
||||
} // namespace anonymous
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -907,6 +927,10 @@ static void android_media_MediaDrm_native_init(JNIEnv *env) {
|
||||
FIND_CLASS(clazz, "android/media/MediaDrm$KeyStatus");
|
||||
gFields.keyStatus.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
GET_METHOD_ID(gFields.keyStatus.init, clazz, "<init>", "([BI)V");
|
||||
|
||||
FIND_CLASS(clazz, "android/media/MediaDrm$LogMessage");
|
||||
gFields.logMessage.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
|
||||
GET_METHOD_ID(gFields.logMessage.init, clazz, "<init>", "(JILjava/lang/String;)V");
|
||||
}
|
||||
|
||||
static void android_media_MediaDrm_native_setup(
|
||||
@@ -1996,6 +2020,22 @@ static void android_media_MediaDrm_setPlaybackId(
|
||||
throwExceptionAsNecessary(env, err, "Failed to set playbackId");
|
||||
}
|
||||
|
||||
static jobject android_media_MediaDrm_getLogMessages(
|
||||
JNIEnv *env, jobject thiz) {
|
||||
sp<IDrm> drm = GetDrm(env, thiz);
|
||||
if (!CheckDrm(env, drm)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Vector<drm::V1_4::LogMessage> logs;
|
||||
status_t err = drm->getLogMessages(logs);
|
||||
ALOGI("drm->getLogMessages %zu logs", logs.size());
|
||||
if (throwExceptionAsNecessary(env, err, "Failed to get log messages")) {
|
||||
return NULL;
|
||||
}
|
||||
return hidlLogMessagesToJavaList(env, logs);
|
||||
}
|
||||
|
||||
static const JNINativeMethod gMethods[] = {
|
||||
{ "native_release", "()V", (void *)android_media_MediaDrm_native_release },
|
||||
|
||||
@@ -2123,6 +2163,9 @@ static const JNINativeMethod gMethods[] = {
|
||||
|
||||
{ "setPlaybackId", "([BLjava/lang/String;)V",
|
||||
(void *)android_media_MediaDrm_setPlaybackId },
|
||||
|
||||
{ "getLogMessages", "()Ljava/util/List;",
|
||||
(void *)android_media_MediaDrm_getLogMessages },
|
||||
};
|
||||
|
||||
int register_android_media_Drm(JNIEnv *env) {
|
||||
|
||||
Reference in New Issue
Block a user