diff options
author | Arne Schwabe <arne@rfc2549.org> | 2014-01-16 23:13:41 +0100 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2014-01-16 23:13:41 +0100 |
commit | 5ee6a9d698e6231f37a6d2a47e05459d107fb049 (patch) | |
tree | 04565f68ac3b3de05e44f6439df6a1f9a847ec5f /src/de/blinkt/openvpn/views | |
parent | fa8d545becf246b6f09d2fb6392d4cc25788346f (diff) |
Switch to android file dialog on 4.4 for importing pkcs12, certificates and key files
Diffstat (limited to 'src/de/blinkt/openvpn/views')
-rw-r--r-- | src/de/blinkt/openvpn/views/FileSelectLayout.java | 277 |
1 files changed, 196 insertions, 81 deletions
diff --git a/src/de/blinkt/openvpn/views/FileSelectLayout.java b/src/de/blinkt/openvpn/views/FileSelectLayout.java index 7ee96884..57ccd895 100644 --- a/src/de/blinkt/openvpn/views/FileSelectLayout.java +++ b/src/de/blinkt/openvpn/views/FileSelectLayout.java @@ -1,8 +1,17 @@ package de.blinkt.openvpn.views; +import android.annotation.TargetApi; +import android.app.Activity; +import android.net.Uri; +import android.os.Build; +import android.text.TextUtils; +import android.text.style.CharacterStyle; +import android.util.Base64; +import android.webkit.MimeTypeMap; import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile; import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.core.VpnStatus; import de.blinkt.openvpn.core.X509Utils; import android.app.Fragment; import android.content.Context; @@ -15,91 +24,197 @@ import android.widget.Button; import android.widget.LinearLayout; import android.widget.TextView; +import java.io.*; +import java.util.TreeSet; +import java.util.Vector; + +import static android.os.Build.*; + public class FileSelectLayout extends LinearLayout implements OnClickListener { + public void parseResponse(Intent data, Context c) { + if (VERSION.SDK_INT < VERSION_CODES.KITKAT) { + String fileData = data.getStringExtra(FileSelect.RESULT_DATA); + setData(fileData, c); + } else if (data != null) { + Uri uri = data.getData(); + try { + byte[] fileData = readBytesFromStream(c.getContentResolver().openInputStream(uri)); + String newData = null; + switch (fileType) { + case CERTIFICATE: + case KEYFILE: + newData = new String(fileData, "UTF-8"); + break; + case PKCS12: + newData = Base64.encodeToString(fileData, Base64.DEFAULT); + break; + } + setData(VpnProfile.INLINE_TAG + newData, c); + + } catch (IOException e) { + VpnStatus.logException(e); + } + + + } + } + + static private byte[] readBytesFromStream(InputStream input) throws IOException { + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + int nRead; + byte[] data = new byte[16384]; + + while ((nRead = input.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + buffer.flush(); + input.close(); + return buffer.toByteArray(); + } + + public enum FileType { + PKCS12, + CERTIFICATE, + KEYFILE + } + private final boolean mIsCertificate; private TextView mDataView; - private String mData; - private Fragment mFragment; - private int mTaskId; - private Button mSelectButton; - private boolean mBase64Encode; - private String mTitle; - private boolean mShowClear; - private TextView mDataDetails; - - public FileSelectLayout( Context context, AttributeSet attrset) { - super(context,attrset); - inflate(getContext(), R.layout.file_select, this); - - TypedArray ta = context.obtainStyledAttributes(attrset, R.styleable.FileSelectLayout); - - mTitle = ta.getString(R.styleable.FileSelectLayout_title); - mIsCertificate = ta.getBoolean(R.styleable.FileSelectLayout_certificate,true); - - TextView tview = (TextView) findViewById(R.id.file_title); - tview.setText(mTitle); - - mDataView = (TextView) findViewById(R.id.file_selected_item); - mDataDetails = (TextView) findViewById(R.id.file_selected_description); - mSelectButton = (Button) findViewById(R.id.file_select_button); - mSelectButton.setOnClickListener(this); - - ta.recycle(); - } - - public void setFragment(Fragment fragment, int i) - { - mTaskId = i; - mFragment = fragment; - } - - public void getCertificateFileDialog() { - Intent startFC = new Intent(getContext(),FileSelect.class); - startFC.putExtra(FileSelect.START_DATA, mData); - startFC.putExtra(FileSelect.WINDOW_TITLE,mTitle); - if(mBase64Encode) - startFC.putExtra(FileSelect.DO_BASE64_ENCODE, true); - if(mShowClear) - startFC.putExtra(FileSelect.SHOW_CLEAR_BUTTON, true); - mFragment.startActivityForResult(startFC,mTaskId); - } - - - public String getData() { - return mData; - } - - public void setData(String data, Context c) { - mData = data; - if(data==null) { - mDataView.setText(mFragment.getString(R.string.no_data)); - mDataDetails.setText(""); - }else { - if(mData.startsWith(VpnProfile.INLINE_TAG)) - mDataView.setText(R.string.inline_file_data); - else - mDataView.setText(data); - if(mIsCertificate) - mDataDetails.setText(X509Utils.getCertificateFriendlyName(c,data)); - } - - } - - @Override - public void onClick(View v) { - if(v == mSelectButton) { - getCertificateFileDialog(); - } - } - - public void setBase64Encode() { - mBase64Encode =true; - } - - public void setShowClear() { - mShowClear=true; - } + private String mData; + private Fragment mFragment; + private int mTaskId; + private Button mSelectButton; + private FileType fileType; + private String mTitle; + private boolean mShowClear; + private TextView mDataDetails; + + public FileSelectLayout(Context context, AttributeSet attrset) { + super(context, attrset); + inflate(getContext(), R.layout.file_select, this); + + TypedArray ta = context.obtainStyledAttributes(attrset, R.styleable.FileSelectLayout); + + mTitle = ta.getString(R.styleable.FileSelectLayout_title); + mIsCertificate = ta.getBoolean(R.styleable.FileSelectLayout_certificate, true); + + TextView tview = (TextView) findViewById(R.id.file_title); + tview.setText(mTitle); + + mDataView = (TextView) findViewById(R.id.file_selected_item); + mDataDetails = (TextView) findViewById(R.id.file_selected_description); + mSelectButton = (Button) findViewById(R.id.file_select_button); + mSelectButton.setOnClickListener(this); + + ta.recycle(); + } + + public void setFragment(Fragment fragment, int i, FileType ft) { + mTaskId = i; + mFragment = fragment; + fileType = ft; + } + + public void getCertificateFileDialog() { + Intent startFC = new Intent(getContext(), FileSelect.class); + startFC.putExtra(FileSelect.START_DATA, mData); + startFC.putExtra(FileSelect.WINDOW_TITLE, mTitle); + if (fileType == FileType.PKCS12) + startFC.putExtra(FileSelect.DO_BASE64_ENCODE, true); + if (mShowClear) + startFC.putExtra(FileSelect.SHOW_CLEAR_BUTTON, true); + + mFragment.startActivityForResult(startFC, mTaskId); + } + + + public String getData() { + return mData; + } + + public void setData(String data, Context c) { + mData = data; + if (data == null) { + mDataView.setText(mFragment.getString(R.string.no_data)); + mDataDetails.setText(""); + } else { + if (mData.startsWith(VpnProfile.INLINE_TAG)) + mDataView.setText(R.string.inline_file_data); + else + mDataView.setText(data); + if (mIsCertificate) + mDataDetails.setText(X509Utils.getCertificateFriendlyName(c, data)); + } + + } + + @Override + public void onClick(View v) { + if (v == mSelectButton) { + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) + startFilePicker(); + else + getCertificateFileDialog(); + } + } + + + @TargetApi(VERSION_CODES.KITKAT) + private void startFilePicker() { + + + Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + TreeSet<String> supportedMimeTypes = new TreeSet<String>(); + Vector<String> extensions = new Vector<String>(); + + switch (fileType) { + case PKCS12: + i.setType("application/x-pkcs12"); + supportedMimeTypes.add("application/x-pkcs12"); + extensions.add("p12"); + extensions.add("pfx"); + break; + case CERTIFICATE: + i.setType("application/x-pem-file"); + supportedMimeTypes.add("application/x-x509-ca-cert"); + supportedMimeTypes.add("application/x-x509-user-cert"); + supportedMimeTypes.add("application/x-pem-file"); + supportedMimeTypes.add("text/plain"); + + extensions.add("pem"); + extensions.add("crt"); + break; + case KEYFILE: + i.setType("application/x-pem-file"); + supportedMimeTypes.add("application/x-pem-file"); + supportedMimeTypes.add("application/pkcs8"); + extensions.add("key"); + break; + } + + MimeTypeMap mtm = MimeTypeMap.getSingleton(); + + for (String ext : new String[]{"ovpn", "conf"}) { + String mimeType = mtm.getMimeTypeFromExtension(ext); + if (mimeType != null) + supportedMimeTypes.add(mimeType); + else + supportedMimeTypes.add("application/octet-stream"); + } + + + i.putExtra(Intent.EXTRA_MIME_TYPES, supportedMimeTypes.toArray(new String[supportedMimeTypes.size()])); + mFragment.startActivityForResult(i, mTaskId); + } + + public void setShowClear() { + mShowClear = true; + } } |