<commit_before>package com.kaltura.playersdk;

import android.content.Context;
import android.drm.DrmErrorEvent;
import android.drm.DrmEvent;
import android.drm.DrmInfoEvent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;

import com.kaltura.playersdk.helpers.CacheManager;
import com.kaltura.playersdk.widevine.WidevineDrmClient;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.Collections;


/**
 * Created by noamt on 04/01/2016.
 */
public class LocalAssetsManager {

    private static final String TAG = "LocalAssetsManager";
    private static final int JSON_BYTE_LIMIT = 1024 * 1024;
    
    public interface AssetRegistrationListener {
        void onRegistered(String assetPath);
        void onFailed(String assetPath, Exception error);
    }
    
    public interface AssetStatusListener {
        void onStatus(String assetPath, int expiryTimeSeconds, int availableTimeSeconds);
    }
    
    public interface AssetRemovalListener {
        void onRemoved(String assetPath);
    }
    
    private static void doInBackground(Runnable runnable) {
        new Thread(runnable).start();
    }
    
    public static boolean refreshAsset(@NonNull final Context context, @NonNull final KPPlayerConfig entry, @NonNull final String flavor,
                                        @NonNull final String localPath, @Nullable final AssetRegistrationListener listener) {
        
        // TODO: Refresh
        
        // for now, just re-register.
        return registerAsset(context, entry, flavor, localPath, listener);
    }
    
    public static boolean unregisterAsset(@NonNull final Context context, @NonNull final String localPath, final AssetRemovalListener listener) {

        doInBackground(new Runnable() {
            @Override
            public void run() {
                // Remove cache
                // TODO

                // Remove license
                WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
                widevineDrmClient.setEventListener(new WidevineDrmClient.EventListener() {
                    @Override
                    public void onError(DrmErrorEvent event) {
                        Log.d(TAG, event.toString());
                    }

                    @Override
                    public void onEvent(DrmEvent event) {
                        Log.d(TAG, event.toString());
                        switch (event.getType()) {
                            case DrmInfoEvent.TYPE_RIGHTS_REMOVED:
                                if (listener != null) {
                                    listener.onRemoved(localPath);
                                }
                                break;
                        }
                    }
                });
                widevineDrmClient.removeRights(localPath);
                widevineDrmClient.release();
            }
        });
        return true;
    }

    public static boolean checkAssetStatus(@NonNull final Context context, @NonNull final String localPath, 
                                           @Nullable final AssetStatusListener listener) {

        doInBackground(new Runnable() {
            @Override
            public void run() {
                WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
                WidevineDrmClient.RightsInfo info = widevineDrmClient.getRightsInfo(localPath);
                if (listener != null) {
                    listener.onStatus(localPath, info.expiryTime, info.availableTime);
                }
                widevineDrmClient.release();
            }
        });
        
        return true;
    }


    public static boolean registerAsset(@NonNull final Context context, @NonNull final KPPlayerConfig entry, @NonNull final String flavor,
                                        @NonNull final String localPath, @Nullable final AssetRegistrationListener listener) {

        // NOTE: this method currently only supports (and assumes) Widevine Classic.

        // Preflight: check that all parameters are valid.
        checkNotNull(entry.getPartnerId(), "entry.partnerId");    // can be an empty string (but not null)
        checkNotEmpty(entry.getServerURL(), "entry.domain");
        checkNotEmpty(entry.getUiConfId(), "entry.uiConfId");
        checkNotEmpty(entry.getEntryId(), "entry.entryId");
        checkNotEmpty(flavor, "flavor");
        checkNotEmpty(localPath, "localPath");
        
        
        final DRMScheme drmScheme = DRMScheme.WidevineClassic;

        new Thread() {
            @Override
            public void run() {
                CacheManager.getInstance().setContext(context);
                CacheManager.getInstance().setBaseURL(Utilities.stripLastUriPathSegment(entry.getServerURL()));                
                CacheManager.getInstance().setCacheSize(entry.getCacheSize());
                try {
                    CacheManager.getInstance().getResponse(Uri.parse(entry.getVideoURL()), Collections.<String, String>emptyMap(), "GET");
                } catch (IOException e) {
                    e.printStackTrace();
                    listener.onFailed(localPath, e);
                    return;
                }
                if (!Uri.parse(localPath).getPath().endsWith(".wvm")) {
                    listener.onRegistered(localPath);
                    return;
                }
                Uri licenseUri;
                try {
                    licenseUri = prepareLicenseUri(entry, flavor, drmScheme);
                    registerWidevineClassicAsset(context, localPath, licenseUri, listener);
                } catch (JSONException e) {
                    Log.e(TAG, "JSON error", e);
                    if (listener != null) {
                        listener.onFailed(localPath, e);
                    }
                } catch (IOException e) {
                    Log.e(TAG, "IO error", e);
                    if (listener != null) {
                        listener.onFailed(localPath, e);
                    }
                }
            }
        }.start();
        

        return true;
    }
    
    private static void registerWidevineClassicAsset(@NonNull Context context, @NonNull final String localPath, Uri licenseUri, @Nullable final AssetRegistrationListener listener) {

        WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
        widevineDrmClient.setEventListener(new WidevineDrmClient.EventListener() {
            @Override
            public void onError(DrmErrorEvent event) {
                Log.d(TAG, event.toString());

                if (listener != null) {
                    listener.onFailed(localPath, new Exception("License acquisition failed; DRM client error code: " + event.getType()));
                }
            }

            @Override<commit_msg>LocalAssetsManager: read entire cache response and close the stream. Cleanup.<commit_after>package com.kaltura.playersdk;

import android.content.Context;
import android.drm.DrmErrorEvent;
import android.drm.DrmEvent;
import android.drm.DrmInfoEvent;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.webkit.WebResourceResponse;

import com.kaltura.playersdk.helpers.CacheManager;
import com.kaltura.playersdk.widevine.WidevineDrmClient;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;


/**
 * Created by noamt on 04/01/2016.
 */
public class LocalAssetsManager {

    private static final String TAG = "LocalAssetsManager";
    private static final int JSON_BYTE_LIMIT = 1024 * 1024;
    
    public interface AssetRegistrationListener {
        void onRegistered(String assetPath);
        void onFailed(String assetPath, Exception error);
    }
    
    public interface AssetStatusListener {
        void onStatus(String assetPath, int expiryTimeSeconds, int availableTimeSeconds);
    }
    
    public interface AssetRemovalListener {
        void onRemoved(String assetPath);
    }
    
    private static void doInBackground(Runnable runnable) {
        new Thread(runnable).start();
    }
    
    public static boolean refreshAsset(@NonNull final Context context, @NonNull final KPPlayerConfig entry, @NonNull final String flavor,
                                        @NonNull final String localPath, @Nullable final AssetRegistrationListener listener) {
        
        // TODO: Refresh
        
        // for now, just re-register.
        return registerAsset(context, entry, flavor, localPath, listener);
    }
    
    public static boolean unregisterAsset(@NonNull final Context context, @NonNull final String localPath, final AssetRemovalListener listener) {

        doInBackground(new Runnable() {
            @Override
            public void run() {
                // Remove cache
                // TODO

                // Remove license
                WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
                widevineDrmClient.setEventListener(new WidevineDrmClient.EventListener() {
                    @Override
                    public void onError(DrmErrorEvent event) {
                        Log.d(TAG, event.toString());
                    }

                    @Override
                    public void onEvent(DrmEvent event) {
                        Log.d(TAG, event.toString());
                        switch (event.getType()) {
                            case DrmInfoEvent.TYPE_RIGHTS_REMOVED:
                                if (listener != null) {
                                    listener.onRemoved(localPath);
                                }
                                break;
                        }
                    }
                });
                widevineDrmClient.removeRights(localPath);
                widevineDrmClient.release();
            }
        });
        return true;
    }

    public static boolean checkAssetStatus(@NonNull final Context context, @NonNull final String localPath, 
                                           @Nullable final AssetStatusListener listener) {

        doInBackground(new Runnable() {
            @Override
            public void run() {
                WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
                WidevineDrmClient.RightsInfo info = widevineDrmClient.getRightsInfo(localPath);
                if (listener != null) {
                    listener.onStatus(localPath, info.expiryTime, info.availableTime);
                }
                widevineDrmClient.release();
            }
        });
        
        return true;
    }


    public static boolean registerAsset(@NonNull final Context context, @NonNull final KPPlayerConfig entry, @NonNull final String flavor,
                                        @NonNull final String localPath, @Nullable final AssetRegistrationListener listener) {

        // NOTE: this method currently only supports (and assumes) Widevine Classic.

        // Preflight: check that all parameters are valid.
        checkNotNull(entry.getPartnerId(), "entry.partnerId");    // can be an empty string (but not null)
        checkNotEmpty(entry.getServerURL(), "entry.domain");
        checkNotEmpty(entry.getUiConfId(), "entry.uiConfId");
        checkNotEmpty(entry.getEntryId(), "entry.entryId");
        checkNotEmpty(flavor, "flavor");
        checkNotEmpty(localPath, "localPath");
        
        
        final DRMScheme drmScheme = DRMScheme.WidevineClassic;

        doInBackground(new Runnable() {
            @Override
            public void run() {
                CacheManager cacheManager = CacheManager.getInstance();
                cacheManager.setContext(context);
                cacheManager.setBaseURL(Utilities.stripLastUriPathSegment(entry.getServerURL()));
                cacheManager.setCacheSize(entry.getCacheSize());
                try {
                    WebResourceResponse resp = cacheManager.getResponse(Uri.parse(entry.getVideoURL()), Collections.<String, String>emptyMap(), "GET");
                    // TODO: avoid this redundant object creation.
                    InputStream inputStream = resp.getData();
                    Utilities.fullyReadInputStream(inputStream, 10*1024*1024);
                    inputStream.close();
                } catch (IOException e) {
                    if (listener != null) {
                        listener.onFailed(localPath, e);
                    }
                    return;
                }
                if (!Uri.parse(localPath).getPath().endsWith(".wvm")) {
                    if (listener != null) {
                        listener.onRegistered(localPath);
                    }
                    return;
                }
                
                try {
                    Uri licenseUri = prepareLicenseUri(entry, flavor, drmScheme);
                    registerWidevineClassicAsset(context, localPath, licenseUri, listener);
                } catch (JSONException | IOException e) {
                    Log.e(TAG, "Error", e);
                    if (listener != null) {
                        listener.onFailed(localPath, e);
                    }
                }
            }
        });

        return true;
    }
    
    private static void registerWidevineClassicAsset(@NonNull Context context, @NonNull final String localPath, Uri licenseUri, @Nullable final AssetRegistrationListener listener) {

        WidevineDrmClient widevineDrmClient = new WidevineDrmClient(context);
        widevineDrmClient.setEventListener(new WidevineDrmClient.EventListener() {
            @Override
            public void onError(DrmErrorEvent event) {
                Log.d(TAG, event.toString());

                if (listener != null) {
                    listener.onFailed(localPath, new Exception("License acquisition failed; DRM client error code: " + event.getType()));
                }
            }

            @Override
{'fraction_non_alphanumeric': 0.08137330618549463, 'fraction_numerical': 0.0029488169627185285, 'mean_word_length': 1.7940368772067476, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5108042', 'n_tokens_mistral': 3566, 'n_tokens_neox': 3300, 'n_words': 790}