<commit_before>package org.commcare.views.widgets;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import org.commcare.CommCareApplication;
import org.commcare.activities.FormEntryActivity;
import org.commcare.activities.components.FormEntryInstanceState;
import org.commcare.dalvik.R;
import org.commcare.logic.PendingCalloutInterface;
import org.commcare.models.encryption.EncryptionIO;
import org.commcare.preferences.HiddenPreferences;
import org.commcare.util.LogTypes;
import org.commcare.utils.FileExtensionNotFoundException;
import org.commcare.utils.FileUtil;
import org.commcare.utils.FormUploadUtil;
import org.commcare.utils.StringUtils;
import org.commcare.utils.UriToFilePath;
import org.javarosa.core.io.StreamsUtil;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.data.IntegerData;
import org.javarosa.core.model.data.InvalidData;
import org.javarosa.core.model.data.StringData;
import org.javarosa.core.services.Logger;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.form.api.FormEntryPrompt;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.crypto.spec.SecretKeySpec;

import androidx.annotation.NonNull;

/**
 * Generic logic for capturing or choosing audio/video/image media
 *
 * @author <NAME> (<EMAIL>)
 */
public abstract class MediaWidget extends QuestionWidget {
    private static final String TAG = MediaWidget.class.getSimpleName();

    protected static final String CUSTOM_TAG = "custom";
    public static final String AES_EXTENSION = ".aes";

    protected Button mCaptureButton;
    protected Button mPlayButton;
    protected Button mChooseButton;
    protected String mBinaryName;
    private String mTempBinaryPath;


    protected final PendingCalloutInterface pendingCalloutInterface;
    protected final String mInstanceFolder;

    private int oversizedMediaSize;

    protected String customFileTag;
    private String destMediaPath;

    public MediaWidget(Context context, FormEntryPrompt prompt,
                       PendingCalloutInterface pendingCalloutInterface) {
        super(context, prompt);

        this.pendingCalloutInterface = pendingCalloutInterface;

        mInstanceFolder = FormEntryInstanceState.getInstanceFolder();

        setOrientation(LinearLayout.VERTICAL);
        initializeButtons();
        setupLayout();
    }


    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == View.VISIBLE) {
            loadAnswerFromDataModel();
        }
    }

    private void loadAnswerFromDataModel() {
        mBinaryName = mPrompt.getAnswerText();
        if (mBinaryName != null) {
            reloadFile();
        } else {
            checkForOversizedMedia(mPrompt.getAnswerValue());
            togglePlayButton(false);
        }
    }

    private void reloadFile() {
        File f = new File(mInstanceFolder + mBinaryName);
        if (f.exists()) {
            checkFileSize(f);
        } else if (mTempBinaryPath == null) {
            File encryptedFile = new File(mInstanceFolder + mBinaryName + AES_EXTENSION);
            checkFileSize(encryptedFile);
            mTempBinaryPath = decryptMedia(encryptedFile, getSecretKey());
        } else {
            checkFileSize(new File(mTempBinaryPath));
        }

        togglePlayButton(true);
    }

    protected String getSourceFilePathToDisplay() {
        File f = new File(mInstanceFolder + mBinaryName);
        if (f.exists()) {
            return f.getAbsolutePath();
        } else {
            // file should have been decrypted at the temp path
            return mTempBinaryPath;
        }
    }

    // decrypt the given file to a temp path
    public static String decryptMedia(File f, SecretKeySpec secretKey) {
        if (!f.getName().endsWith(AES_EXTENSION)) {
            return null;
        }

        String tempMediaPath = createTempMediaPath(FileUtil.getExtension(f.getName()));
        try {
            FileOutputStream fos = new FileOutputStream(tempMediaPath);
            InputStream is = EncryptionIO.getFileInputStream(f.getPath(), secretKey);
            StreamsUtil.writeFromInputToOutputNew(is, fos);<commit_msg>Fix issue with tmp file using aes encryption<commit_after>package org.commcare.views.widgets;

import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;

import org.commcare.CommCareApplication;
import org.commcare.activities.FormEntryActivity;
import org.commcare.activities.components.FormEntryInstanceState;
import org.commcare.dalvik.R;
import org.commcare.logic.PendingCalloutInterface;
import org.commcare.models.encryption.EncryptionIO;
import org.commcare.preferences.HiddenPreferences;
import org.commcare.util.LogTypes;
import org.commcare.utils.FileExtensionNotFoundException;
import org.commcare.utils.FileUtil;
import org.commcare.utils.FormUploadUtil;
import org.commcare.utils.StringUtils;
import org.commcare.utils.UriToFilePath;
import org.javarosa.core.io.StreamsUtil;
import org.javarosa.core.model.data.IAnswerData;
import org.javarosa.core.model.data.IntegerData;
import org.javarosa.core.model.data.InvalidData;
import org.javarosa.core.model.data.StringData;
import org.javarosa.core.services.Logger;
import org.javarosa.core.services.locale.Localization;
import org.javarosa.form.api.FormEntryPrompt;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.crypto.spec.SecretKeySpec;

import androidx.annotation.NonNull;

/**
 * Generic logic for capturing or choosing audio/video/image media
 *
 * @author <NAME> (<EMAIL>)
 */
public abstract class MediaWidget extends QuestionWidget {
    private static final String TAG = MediaWidget.class.getSimpleName();

    protected static final String CUSTOM_TAG = "custom";
    public static final String AES_EXTENSION = ".aes";

    protected Button mCaptureButton;
    protected Button mPlayButton;
    protected Button mChooseButton;
    protected String mBinaryName;
    private String mTempBinaryPath;


    protected final PendingCalloutInterface pendingCalloutInterface;
    protected final String mInstanceFolder;

    private int oversizedMediaSize;

    protected String customFileTag;
    private String destMediaPath;

    public MediaWidget(Context context, FormEntryPrompt prompt,
                       PendingCalloutInterface pendingCalloutInterface) {
        super(context, prompt);

        this.pendingCalloutInterface = pendingCalloutInterface;

        mInstanceFolder = FormEntryInstanceState.getInstanceFolder();

        setOrientation(LinearLayout.VERTICAL);
        initializeButtons();
        setupLayout();
    }


    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == View.VISIBLE) {
            loadAnswerFromDataModel();
        }
    }

    private void loadAnswerFromDataModel() {
        mBinaryName = mPrompt.getAnswerText();
        if (mBinaryName != null) {
            reloadFile();
        } else {
            checkForOversizedMedia(mPrompt.getAnswerValue());
            togglePlayButton(false);
        }
    }

    private void reloadFile() {
        File f = new File(mInstanceFolder + mBinaryName);
        if (f.exists()) {
            checkFileSize(f);
        } else if (mTempBinaryPath == null) {
            File encryptedFile = new File(mInstanceFolder + mBinaryName + AES_EXTENSION);
            checkFileSize(encryptedFile);
            mTempBinaryPath = decryptMedia(encryptedFile, getSecretKey());
        } else {
            checkFileSize(new File(mTempBinaryPath));
        }

        togglePlayButton(true);
    }

    protected String getSourceFilePathToDisplay() {
        File f = new File(mInstanceFolder + mBinaryName);
        if (f.exists()) {
            return f.getAbsolutePath();
        } else {
            // file should have been decrypted at the temp path
            return mTempBinaryPath;
        }
    }

    // decrypt the given file to a temp path
    public static String decryptMedia(File f, SecretKeySpec secretKey) {
        if (!f.getName().endsWith(AES_EXTENSION)) {
            return null;
        }

        String tempMediaPath = createTempMediaPath(FileUtil.getExtension(removeAESExtension(f.getName())));
        try {
            FileOutputStream fos = new FileOutputStream(tempMediaPath);
            InputStream is = EncryptionIO.getFileInputStream(f.getPath(), secretKey);
            StreamsUtil.writeFromInputToOutputNew(is, fos);
{'fraction_non_alphanumeric': 0.08622728738845285, 'fraction_numerical': 0.0, 'mean_word_length': 3.485053037608486, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '670684', 'n_tokens_mistral': 2554, 'n_tokens_neox': 2471, 'n_words': 548}