// Path: googlemediaframework/src/main/java/com/google/android/libraries/mediaframework/exoplayerextensions/ExtendedMediaDrmCallback.java
// public interface ExtendedMediaDrmCallback extends MediaDrmCallback {
//     /**
//      * Optional DrmSessionManager. If not provided, the default (StreamingDrmSessionManager) is used.
//      * @return A DrmSessionManager, ready to be opened. 
//      */
//     DrmSessionManager getSessionManager();
// }
// 
// Path: playerSDK/src/main/java/com/kaltura/playersdk/drm/OfflineDrmManager.java
// @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
// public class OfflineDrmManager {
// 
//     private static final String TAG = "OfflineDrmManager";
// 
//     
//     public static DrmSessionManager getSessionManager(Context context) {
//         try {
//             return new OfflineDrmSessionManager(getStorage(context));
//         } catch (UnsupportedDrmException e) {
//             throw new WidevineNotSupportedException(e);
//         }
//     }
//     
//     public static OfflineKeySetStorage getStorage(Context context) {
//         return new OfflineKeySetStorage(context);
//     }
// 
// 
//     static void printAllProperties(MediaDrm mediaDrm) {
//         String[] stringProps = {MediaDrm.PROPERTY_VENDOR, MediaDrm.PROPERTY_VERSION, MediaDrm.PROPERTY_DESCRIPTION, MediaDrm.PROPERTY_ALGORITHMS, "securityLevel", "systemId", "privacyMode", "sessionSharing", "usageReportingSupport", "appId", "origin", "hdcpLevel", "maxHdcpLevel", "maxNumberOfSessions", "numberOfOpenSessions"};
//         String[] byteArrayProps = {MediaDrm.PROPERTY_DEVICE_UNIQUE_ID, "provisioningUniqueId", "serviceCertificate"};
// 
//         Map<String, String> map = new LinkedHashMap<>();
// 
//         for (String prop : stringProps) {
//             try {
//                 map.put(prop, mediaDrm.getPropertyString(prop));
//             } catch (Exception e) {
//                 Log.d(TAG, "Invalid property " + prop);
//             }
//         }
//         for (String prop : byteArrayProps) {
//             try {
//                 map.put(prop, Base64.encodeToString(mediaDrm.getPropertyByteArray(prop), Base64.NO_WRAP));
//             } catch (Exception e) {
//                 Log.d(TAG, "Invalid property " + prop);
//             }
//         }
// 
//         Log.d(TAG, "MediaDrm properties: " + map);
//     }
// 
//     @Nullable
//     static DrmInitData.SchemeInitData getWidevineInitData(@Nullable DrmInitData drmInitData) {
//         
//         if (drmInitData == null) {
//             Log.e(TAG, "No PSSH in media");
//             return null;
//         }
//         
//         DrmInitData.SchemeInitData schemeInitData = drmInitData.get(WIDEVINE_UUID);
//         if (schemeInitData == null) {
//             Log.e(TAG, "No Widevine PSSH in media");
//             return null;
//         }
// 
//         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//             // Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
//             byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData.data, WIDEVINE_UUID);
//             if (psshData == null) {
//                 // Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
//             } else {
//                 schemeInitData = new DrmInitData.SchemeInitData(schemeInitData.mimeType, psshData);
//             }
//         }
//         return schemeInitData;
//     }
// 
//     static MediaDrmSession openSessionWithKeys(MediaDrm mediaDrm, OfflineKeySetStorage storage, byte[] initData) throws MediaDrmException, MediaCryptoException, FileNotFoundException {
// 
//         byte[] keySetId = storage.loadKeySetId(initData);
// 
//         MediaDrmSession session = MediaDrmSession.open(mediaDrm);
//         session.restoreKeys(keySetId);
//         
//         Map<String, String> keyStatus = session.queryKeyStatus();
//         Log.d(TAG, "keyStatus: " + keyStatus);
//         
//         return session;
//     }
// } 


import android.annotation.TargetApi;
import android.content.Context;
import android.media.MediaDrm;
import android.os.Build;
import android.util.Base64;
import android.util.Log;
import com.google.android.exoplayer.drm.DrmSessionManager;
import com.google.android.libraries.mediaframework.exoplayerextensions.ExoplayerUtil;
import com.google.android.libraries.mediaframework.exoplayerextensions.ExtendedMediaDrmCallback;
import com.kaltura.playersdk.BuildConfig;
import com.kaltura.playersdk.drm.OfflineDrmManager;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
        synchronized (mLicenseLock) {
            // No uri? wait.
            if (mLicenseUri == null) {
                try {
                    mLicenseLock.wait(MAX_LICENCE_URI_WAIT);
                } catch (InterruptedException e) {
                    Log.d(TAG, "Interrupted", e);
                }
            }
            // Still no uri? throw.
            if (mLicenseUri == null) {
                throw new IllegalStateException("licenseUri cannot be null");
            }
            // Execute request.
            byte[] response = ExoplayerUtil.executePost(mLicenseUri, request.getData(), headers);
            Log.d(TAG, "response data (b64): " + Base64.encodeToString(response, 0));
            return response;
        }
    }

    public void setLicenseUri(String licenseUri) {
        synchronized (mLicenseLock) {
            mLicenseUri = licenseUri;
            // notify executeKeyRequest() that we have the license uri.
            mLicenseLock.notify();
        }
    }

    @Override
    public DrmSessionManager getSessionManager() {
// Path: googlemediaframework/src/main/java/com/google/android/libraries/mediaframework/exoplayerextensions/ExtendedMediaDrmCallback.java
// public interface ExtendedMediaDrmCallback extends MediaDrmCallback {
//     /**
//      * Optional DrmSessionManager. If not provided, the default (StreamingDrmSessionManager) is used.
//      * @return A DrmSessionManager, ready to be opened. 
//      */
//     DrmSessionManager getSessionManager();
// }
// 
// Path: playerSDK/src/main/java/com/kaltura/playersdk/drm/OfflineDrmManager.java
// @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
// public class OfflineDrmManager {
// 
//     private static final String TAG = "OfflineDrmManager";
// 
//     
//     public static DrmSessionManager getSessionManager(Context context) {
//         try {
//             return new OfflineDrmSessionManager(getStorage(context));
//         } catch (UnsupportedDrmException e) {
//             throw new WidevineNotSupportedException(e);
//         }
//     }
//     
//     public static OfflineKeySetStorage getStorage(Context context) {
//         return new OfflineKeySetStorage(context);
//     }
// 
// 
//     static void printAllProperties(MediaDrm mediaDrm) {
//         String[] stringProps = {MediaDrm.PROPERTY_VENDOR, MediaDrm.PROPERTY_VERSION, MediaDrm.PROPERTY_DESCRIPTION, MediaDrm.PROPERTY_ALGORITHMS, "securityLevel", "systemId", "privacyMode", "sessionSharing", "usageReportingSupport", "appId", "origin", "hdcpLevel", "maxHdcpLevel", "maxNumberOfSessions", "numberOfOpenSessions"};
//         String[] byteArrayProps = {MediaDrm.PROPERTY_DEVICE_UNIQUE_ID, "provisioningUniqueId", "serviceCertificate"};
// 
//         Map<String, String> map = new LinkedHashMap<>();
// 
//         for (String prop : stringProps) {
//             try {
//                 map.put(prop, mediaDrm.getPropertyString(prop));
//             } catch (Exception e) {
//                 Log.d(TAG, "Invalid property " + prop);
//             }
//         }
//         for (String prop : byteArrayProps) {
//             try {
//                 map.put(prop, Base64.encodeToString(mediaDrm.getPropertyByteArray(prop), Base64.NO_WRAP));
//             } catch (Exception e) {
//                 Log.d(TAG, "Invalid property " + prop);
//             }
//         }
// 
//         Log.d(TAG, "MediaDrm properties: " + map);
//     }
// 
//     @Nullable
//     static DrmInitData.SchemeInitData getWidevineInitData(@Nullable DrmInitData drmInitData) {
//         
//         if (drmInitData == null) {
//             Log.e(TAG, "No PSSH in media");
//             return null;
//         }
//         
//         DrmInitData.SchemeInitData schemeInitData = drmInitData.get(WIDEVINE_UUID);
//         if (schemeInitData == null) {
//             Log.e(TAG, "No Widevine PSSH in media");
//             return null;
//         }
// 
//         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//             // Prior to L the Widevine CDM required data to be extracted from the PSSH atom.
//             byte[] psshData = PsshAtomUtil.parseSchemeSpecificData(schemeInitData.data, WIDEVINE_UUID);
//             if (psshData == null) {
//                 // Extraction failed. schemeData isn't a Widevine PSSH atom, so leave it unchanged.
//             } else {
//                 schemeInitData = new DrmInitData.SchemeInitData(schemeInitData.mimeType, psshData);
//             }
//         }
//         return schemeInitData;
//     }
// 
//     static MediaDrmSession openSessionWithKeys(MediaDrm mediaDrm, OfflineKeySetStorage storage, byte[] initData) throws MediaDrmException, MediaCryptoException, FileNotFoundException {
// 
//         byte[] keySetId = storage.loadKeySetId(initData);
// 
//         MediaDrmSession session = MediaDrmSession.open(mediaDrm);
//         session.restoreKeys(keySetId);
//         
//         Map<String, String> keyStatus = session.queryKeyStatus();
//         Log.d(TAG, "keyStatus: " + keyStatus);
//         
//         return session;
//     }
// } 


// Path: playerSDK/src/main/java/com/kaltura/playersdk/players/KPlayerExoDrmCallback.java
import android.annotation.TargetApi;
import android.content.Context;
import android.media.MediaDrm;
import android.os.Build;
import android.util.Base64;
import android.util.Log;
import com.google.android.exoplayer.drm.DrmSessionManager;
import com.google.android.libraries.mediaframework.exoplayerextensions.ExoplayerUtil;
import com.google.android.libraries.mediaframework.exoplayerextensions.ExtendedMediaDrmCallback;
import com.kaltura.playersdk.BuildConfig;
import com.kaltura.playersdk.drm.OfflineDrmManager;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

        synchronized (mLicenseLock) {
            // No uri? wait.
            if (mLicenseUri == null) {
                try {
                    mLicenseLock.wait(MAX_LICENCE_URI_WAIT);
                } catch (InterruptedException e) {
                    Log.d(TAG, "Interrupted", e);
                }
            }
            // Still no uri? throw.
            if (mLicenseUri == null) {
                throw new IllegalStateException("licenseUri cannot be null");
            }
            // Execute request.
            byte[] response = ExoplayerUtil.executePost(mLicenseUri, request.getData(), headers);
            Log.d(TAG, "response data (b64): " + Base64.encodeToString(response, 0));
            return response;
        }
    }

    public void setLicenseUri(String licenseUri) {
        synchronized (mLicenseLock) {
            mLicenseUri = licenseUri;
            // notify executeKeyRequest() that we have the license uri.
            mLicenseLock.notify();
        }
    }

    @Override
    public DrmSessionManager getSessionManager() {
        return mOffline ? OfflineDrmManager.getSessionManager(mContext) : null;