18b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol/*
28b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Copyright (c) 2014 Intel Corporation 
38b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
48b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Licensed under the Apache License, Version 2.0 (the "License");
58b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// you may not use this file except in compliance with the License.
68b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// You may obtain a copy of the License at
78b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
88b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//      http://www.apache.org/licenses/LICENSE-2.0
98b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol//
108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// Unless required by applicable law or agreed to in writing, software
118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// distributed under the License is distributed on an "AS IS" BASIS,
128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// See the License for the specific language governing permissions and
148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol// limitations under the License.
158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol*/
168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <HwcTrace.h>
178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <DrmConfig.h>
188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <Hwcomposer.h>
198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <DisplayQuery.h>
208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <common/DrmControl.h>
218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <common/HdcpControl.h>
228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol#include <cutils/properties.h>
238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace android {
268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolnamespace intel {
278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolHdcpControl::HdcpControl()
298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    : mCallback(NULL),
308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mUserData(NULL),
318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mCallbackState(CALLBACK_PENDING),
328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mMutex(),
338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mStoppedCondition(),
348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mCompletedCondition(),
358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mWaitForCompletion(false),
368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mStopped(true),
378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mAuthenticated(false),
388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mActionDelay(0),
398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol      mAuthRetryCount(0)
408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin PujolHdcpControl::~HdcpControl()
448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::startHdcp()
488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // this is a blocking and synchronous call
508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    Mutex::Autolock lock(mMutex);
518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    char prop[PROPERTY_VALUE_MAX];
538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (property_get("debug.hwc.hdcp.enable", prop, "1") > 0) {
548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (atoi(prop) == 0) {
558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            WTRACE("HDCP is disabled");
568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            return false;
578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mStopped) {
618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("HDCP has been started");
628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mStopped = false;
668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mAuthenticated = false;
678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mWaitForCompletion = false;
688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread = new HdcpControlThread(this);
708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mThread.get()) {
718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to create hdcp control thread");
728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!runHdcp()) {
768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to run HDCP");
778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mStopped = true;
788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread = NULL;
798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mAuthRetryCount = 0;
838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mWaitForCompletion = !mAuthenticated;
848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mAuthenticated) {
858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mActionDelay = HDCP_VERIFICATION_DELAY_MS;
868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else {
878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mActionDelay = HDCP_AUTHENTICATION_SHORT_DELAY_MS;
888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread->run("HdcpControl", PRIORITY_NORMAL);
918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mWaitForCompletion) {
938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        // HDCP is authenticated.
948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    status_t err = mCompletedCondition.waitRelative(mMutex, milliseconds(HDCP_AUTHENTICATION_TIMEOUT_MS));
978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (err == -ETIMEDOUT) {
988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("timeout waiting for completion");
998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mWaitForCompletion = false;
1018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return mAuthenticated;
1028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::startHdcpAsync(HdcpStatusCallback cb, void *userData)
1058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    char prop[PROPERTY_VALUE_MAX];
1078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (property_get("debug.hwc.hdcp.enable", prop, "1") > 0) {
1088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (atoi(prop) == 0) {
1098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            WTRACE("HDCP is disabled");
1108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            return false;
1118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (cb == NULL || userData == NULL) {
1158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("invalid callback or user data");
1168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    Mutex::Autolock lock(mMutex);
1208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mStopped) {
1228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("HDCP has been started");
1238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
1248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread = new HdcpControlThread(this);
1278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mThread.get()) {
1288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to create hdcp control thread");
1298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mAuthRetryCount = 0;
1338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mCallback = cb;
1348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mUserData = userData;
1358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mCallbackState = CALLBACK_PENDING;
1368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mWaitForCompletion = false;
1378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mAuthenticated = false;
1388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mStopped = false;
1398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mActionDelay = HDCP_ASYNC_START_DELAY_MS;
1408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    mThread->run("HdcpControl", PRIORITY_NORMAL);
1418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::stopHdcp()
1468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    do {
1488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        Mutex::Autolock lock(mMutex);
1498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mStopped) {
1508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            return true;
1518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
1528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mStopped = true;
1548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mStoppedCondition.signal();
1558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mAuthenticated = false;
1578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mWaitForCompletion = false;
1588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mCallback = NULL;
1598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mUserData = NULL;
1608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        disableAuthentication();
1618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } while (0);
1628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mThread.get()) {
1648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread->requestExitAndWait();
1658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mThread = NULL;
1668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::enableAuthentication()
1728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
1748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandNone(fd, DRM_PSB_ENABLE_HDCP);
1758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
1768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to enable HDCP authentication");
1778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::disableAuthentication()
1838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
1858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandNone(fd, DRM_PSB_DISABLE_HDCP);
1868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
1878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to stop disable authentication");
1888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
1898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
1908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::enableOverlay()
1948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
1958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
1968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
1978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
1988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::disableOverlay()
1998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
2018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::enableDisplayIED()
2048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
2068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandNone(fd, DRM_PSB_HDCP_DISPLAY_IED_ON);
2078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
2088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to enable overlay IED");
2098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
2108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
2128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::disableDisplayIED()
2158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
2178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandNone(fd, DRM_PSB_HDCP_DISPLAY_IED_OFF);
2188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
2198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to disable overlay IED");
2208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
2218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
2238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::isHdcpSupported()
2268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
2288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    unsigned int caps = 0;
2298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandRead(fd, DRM_PSB_QUERY_HDCP, &caps, sizeof(caps));
2308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
2318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to query HDCP capability");
2328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
2338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (caps == 0) {
2358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        WTRACE("HDCP is not supported");
2368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
2378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else {
2388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ITRACE("HDCP is supported");
2398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return true;
2408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::checkAuthenticated()
2448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int fd = Hwcomposer::getInstance().getDrm()->getDrmFd();
2468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    unsigned int match = 0;
2478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    int ret = drmCommandRead(fd, DRM_PSB_GET_HDCP_LINK_STATUS, &match, sizeof(match));
2488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (ret != 0) {
2498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("failed to get hdcp link status");
2508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
2518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (match) {
2538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        VTRACE("HDCP is authenticated");
2548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mAuthenticated = true;
2558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else {
2568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ETRACE("HDCP is not authenticated");
2578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mAuthenticated = false;
2588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
2598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return mAuthenticated;
2608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
2618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::runHdcp()
2638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
2648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // Default return value is true so HDCP can be re-authenticated in the working thread
2658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    bool ret = true;
2668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    preRunHdcp();
2688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    for (int i = 0; i < HDCP_INLOOP_RETRY_NUMBER; i++) {
2708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        VTRACE("enable and verify HDCP, iteration# %d", i);
2718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mStopped) {
2728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            WTRACE("HDCP authentication has been stopped");
2738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ret = false;
2748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            break;
2758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
2768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (!enableAuthentication()) {
2788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ETRACE("HDCP authentication failed. Retry");
2798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mAuthenticated = false;
2808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ret = true;
2818b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        } else {
2828b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ITRACE("HDCP is authenticated");
2838b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mAuthenticated = true;
2848b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ret = true;
2858b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            break;
2868b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
2878b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2888b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mStopped) {
2898b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            WTRACE("HDCP authentication has been stopped");
2908b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            ret = false;
2918b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            break;
2928b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
2938b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
2948b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (i < HDCP_INLOOP_RETRY_NUMBER - 1) {
2958b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            // Adding delay to make sure panel receives video signal so it can start HDCP authentication.
2968b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            // (HDCP spec 1.3, section 2.3)
2978b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            usleep(HDCP_INLOOP_RETRY_DELAY_US);
2988b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
2998b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3008b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3018b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    postRunHdcp();
3028b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3038b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return ret;
3048b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
3058b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3068b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::preRunHdcp()
3078b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
3088b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // TODO: for CTP platform, IED needs to be disabled during HDCP authentication.
3098b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
3108b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
3118b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3128b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::postRunHdcp()
3138b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
3148b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // TODO: for CTP platform, IED needs to be disabled during HDCP authentication.
3158b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return true;
3168b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
3178b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3188b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3198b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolvoid HdcpControl::signalCompletion()
3208b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
3218b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mWaitForCompletion) {
3228b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ITRACE("signal HDCP authentication completed, status = %d", mAuthenticated);
3238b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mCompletedCondition.signal();
3248b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mWaitForCompletion = false;
3258b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3268b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
3278b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3288b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujolbool HdcpControl::threadLoop()
3298b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol{
3308b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    Mutex::Autolock lock(mMutex);
3318b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    status_t err = mStoppedCondition.waitRelative(mMutex, milliseconds(mActionDelay));
3328b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (err != -ETIMEDOUT) {
3338b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ITRACE("Hdcp is stopped.");
3348b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        signalCompletion();
3358b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        return false;
3368b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3378b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3388b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // default is to keep thread active
3398b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    bool ret = true;
3408b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!mAuthenticated) {
3418b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        ret = runHdcp();
3428b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mAuthRetryCount++;
3438b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else {
3448b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mAuthRetryCount = 0;
3458b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        checkAuthenticated();
3468b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3478b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3488b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // set next action delay
3498b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mAuthenticated) {
3508b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        mActionDelay = HDCP_VERIFICATION_DELAY_MS;
3518b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    } else {
3528b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        // If HDCP can not authenticate after "HDCP_RETRY_LIMIT" attempts
3538b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        // reduce HDCP retry frequency to 2 sec
3548b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        if (mAuthRetryCount >= HDCP_RETRY_LIMIT) {
3558b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mActionDelay = HDCP_AUTHENTICATION_LONG_DELAY_MS;
3568b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        } else {
3578b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mActionDelay = HDCP_AUTHENTICATION_SHORT_DELAY_MS;
3588b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
3598b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3608b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3618b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    // TODO: move out of lock?
3628b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (!ret || mAuthenticated) {
3638b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        signalCompletion();
3648b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3658b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3668b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    if (mCallback) {
3678b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol         if ((mAuthenticated && mCallbackState == CALLBACK_AUTHENTICATED) ||
3688b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            (!mAuthenticated && mCallbackState == CALLBACK_NOT_AUTHENTICATED)) {
3698b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            // ignore callback as state is not changed
3708b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        } else {
3718b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            mCallbackState =
3728b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol                mAuthenticated ? CALLBACK_AUTHENTICATED : CALLBACK_NOT_AUTHENTICATED;
3738b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol            (*mCallback)(mAuthenticated, mUserData);
3748b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol        }
3758b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    }
3768b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol    return ret;
3778b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol}
3788b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol
3798b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace intel
3808b0063f7f46289983bd1bf9ca61662b4a2ddf5b6Benjamin Pujol} // namespace android
381