Skip to content
Snippets Groups Projects
Commit 3106dab2 authored by Huihong Luo's avatar Huihong Luo Committed by Android (Google) Code Review
Browse files

Merge "Update HDCP for physical displays" into main

parents 1fde4358 683cc4a8
No related branches found
No related tags found
No related merge requests found
......@@ -286,6 +286,16 @@ public abstract class DisplayEventReceiver {
long renderPeriod) {
}
/**
* Called when a display hdcp levels change event is received.
*
* @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
* @param connectedLevel the new connected HDCP level
* @param maxLevel the maximum HDCP level
*/
public void onHdcpLevelsChanged(long physicalDisplayId, int connectedLevel, int maxLevel) {
}
/**
* Represents a mapping between a UID and an override frame rate
*/
......@@ -374,4 +384,11 @@ public abstract class DisplayEventReceiver {
onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides);
}
// Called from native code.
@SuppressWarnings("unused")
private void dispatchHdcpLevelsChanged(long physicalDisplayId, int connectedLevel,
int maxLevel) {
onHdcpLevelsChanged(physicalDisplayId, connectedLevel, maxLevel);
}
}
......@@ -41,6 +41,7 @@ static struct {
jmethodID dispatchHotplugConnectionError;
jmethodID dispatchModeChanged;
jmethodID dispatchFrameRateOverrides;
jmethodID dispatchHdcpLevelsChanged;
struct {
jclass clazz;
......@@ -96,6 +97,8 @@ private:
void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId,
std::vector<FrameRateOverride> overrides) override;
void dispatchNullEvent(nsecs_t timestamp, PhysicalDisplayId displayId) override {}
void dispatchHdcpLevelsChanged(PhysicalDisplayId displayId, int connectedLevel,
int maxLevel) override;
};
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
......@@ -294,6 +297,22 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides(
mMessageQueue->raiseAndClearException(env, "dispatchModeChanged");
}
void NativeDisplayEventReceiver::dispatchHdcpLevelsChanged(PhysicalDisplayId displayId,
int connectedLevel, int maxLevel) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking hdcp levels changed handler.", this);
env->CallVoidMethod(receiverObj.get(),
gDisplayEventReceiverClassInfo.dispatchHdcpLevelsChanged,
displayId.value, connectedLevel, maxLevel);
ALOGV("receiver %p ~ Returned from hdcp levels changed handler.", this);
}
mMessageQueue->raiseAndClearException(env, "dispatchHdcpLevelsChanged");
}
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak,
jobject messageQueueObj, jint vsyncSource, jint eventRegistration,
jlong layerHandle) {
......@@ -385,6 +404,9 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz,
"dispatchFrameRateOverrides",
"(JJ[Landroid/view/DisplayEventReceiver$FrameRateOverride;)V");
gDisplayEventReceiverClassInfo.dispatchHdcpLevelsChanged =
GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHdcpLevelsChanged",
"(JII)V");
jclass frameRateOverrideClazz =
FindClassOrDie(env, "android/view/DisplayEventReceiver$FrameRateOverride");
......
......@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.hardware.display.DisplayManagerInternal.DisplayOffloadSession;
import android.hardware.sidekick.SidekickInternal;
import android.media.MediaDrm;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
......@@ -242,6 +243,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private SurfaceControl.DisplayMode mActiveSfDisplayMode;
// The active display vsync period in SurfaceFlinger
private float mActiveRenderFrameRate;
// The current HDCP level supported by the display, 0 indicates unset
// values are defined in hardware/interfaces/drm/aidl/android/hardware/drm/HdcpLevel.aidl
private int mConnectedHdcpLevel;
private DisplayEventReceiver.FrameRateOverride[] mFrameRateOverrides =
new DisplayEventReceiver.FrameRateOverride[0];
......@@ -675,8 +680,9 @@ final class LocalDisplayAdapter extends DisplayAdapter {
mInfo.yDpi = mActiveSfDisplayMode.yDpi;
mInfo.deviceProductInfo = mStaticDisplayInfo.deviceProductInfo;
// Assume that all built-in displays that have secure output (eg. HDCP) also
// support compositing from gralloc protected buffers.
if (mConnectedHdcpLevel != 0) {
mStaticDisplayInfo.secure = mConnectedHdcpLevel >= MediaDrm.HDCP_V1;
}
if (mStaticDisplayInfo.secure) {
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
| DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
......@@ -1093,6 +1099,12 @@ final class LocalDisplayAdapter extends DisplayAdapter {
}
}
public void onHdcpLevelsChangedLocked(int connectedLevel, int maxLevel) {
if (updateHdcpLevelsLocked(connectedLevel, maxLevel)) {
updateDeviceInfoLocked();
}
}
public boolean updateActiveModeLocked(int activeSfModeId, float renderFrameRate) {
if (mActiveSfDisplayMode.id == activeSfModeId
&& mActiveRenderFrameRate == renderFrameRate) {
......@@ -1118,6 +1130,22 @@ final class LocalDisplayAdapter extends DisplayAdapter {
return true;
}
public boolean updateHdcpLevelsLocked(int connectedLevel, int maxLevel) {
if (connectedLevel > maxLevel) {
Slog.w(TAG, "HDCP connected level: " + connectedLevel
+ " is larger than max level: " + maxLevel
+ ", ignoring request.");
return false;
}
if (mConnectedHdcpLevel == connectedLevel) {
return false;
}
mConnectedHdcpLevel = connectedLevel;
return true;
}
public void requestColorModeLocked(int colorMode) {
if (mActiveColorMode == colorMode) {
return;
......@@ -1387,6 +1415,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
long renderPeriod);
void onFrameRateOverridesChanged(long timestampNanos, long physicalDisplayId,
DisplayEventReceiver.FrameRateOverride[] overrides);
void onHdcpLevelsChanged(long physicalDisplayId, int connectedLevel, int maxLevel);
}
......@@ -1420,6 +1449,11 @@ final class LocalDisplayAdapter extends DisplayAdapter {
DisplayEventReceiver.FrameRateOverride[] overrides) {
mListener.onFrameRateOverridesChanged(timestampNanos, physicalDisplayId, overrides);
}
@Override
public void onHdcpLevelsChanged(long physicalDisplayId, int connectedLevel, int maxLevel) {
mListener.onHdcpLevelsChanged(physicalDisplayId, connectedLevel, maxLevel);
}
}
private final class LocalDisplayEventListener implements DisplayEventListener {
......@@ -1489,6 +1523,26 @@ final class LocalDisplayAdapter extends DisplayAdapter {
device.onFrameRateOverridesChanged(overrides);
}
}
@Override
public void onHdcpLevelsChanged(long physicalDisplayId, int connectedLevel, int maxLevel) {
if (DEBUG) {
Slog.d(TAG, "onHdcpLevelsChanged(physicalDisplayId=" + physicalDisplayId
+ ", connectedLevel=" + connectedLevel + ", maxLevel=" + maxLevel + ")");
}
synchronized (getSyncRoot()) {
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
if (DEBUG) {
Slog.d(TAG, "Received hdcp levels change for unhandled physical display: "
+ "physicalDisplayId=" + physicalDisplayId);
}
return;
}
device.onHdcpLevelsChangedLocked(connectedLevel, maxLevel);
}
}
}
@VisibleForTesting
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment