|
@@ -0,0 +1,291 @@
|
|
|
+/**
|
|
|
+ * Copyright © 2014-2023 PDF Technologies, Inc. All Rights Reserved.
|
|
|
+ * <p>
|
|
|
+ * THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
|
|
|
+ * AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
|
|
|
+ * UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
|
|
|
+ * This notice may not be removed from this file.
|
|
|
+ */
|
|
|
+
|
|
|
+package com.compdfkit.tools.signature.dialog.create;
|
|
|
+
|
|
|
+import android.app.Dialog;
|
|
|
+import android.content.Intent;
|
|
|
+import android.net.Uri;
|
|
|
+import android.os.Bundle;
|
|
|
+import android.os.Environment;
|
|
|
+import android.text.TextUtils;
|
|
|
+import android.view.LayoutInflater;
|
|
|
+import android.view.View;
|
|
|
+import android.view.ViewGroup;
|
|
|
+import android.widget.LinearLayout;
|
|
|
+import android.widget.Switch;
|
|
|
+import android.widget.ViewSwitcher;
|
|
|
+
|
|
|
+import androidx.activity.ComponentDialog;
|
|
|
+import androidx.activity.OnBackPressedCallback;
|
|
|
+import androidx.activity.result.ActivityResultLauncher;
|
|
|
+import androidx.activity.result.contract.ActivityResultContracts;
|
|
|
+import androidx.annotation.NonNull;
|
|
|
+import androidx.annotation.Nullable;
|
|
|
+import androidx.appcompat.widget.AppCompatButton;
|
|
|
+import androidx.appcompat.widget.AppCompatImageView;
|
|
|
+import androidx.appcompat.widget.AppCompatTextView;
|
|
|
+
|
|
|
+import com.compdfkit.core.document.signature.CPDFCertInfo;
|
|
|
+import com.compdfkit.core.document.signature.CPDFOwnerInfo;
|
|
|
+import com.compdfkit.core.document.signature.CPDFSignature;
|
|
|
+import com.compdfkit.core.document.signature.CPDFX509;
|
|
|
+import com.compdfkit.tools.R;
|
|
|
+import com.compdfkit.tools.common.utils.CFileUtils;
|
|
|
+import com.compdfkit.tools.common.utils.CLog;
|
|
|
+import com.compdfkit.tools.common.utils.dialog.CDialogFragmentUtil;
|
|
|
+import com.compdfkit.tools.common.utils.view.CEditText;
|
|
|
+import com.compdfkit.tools.signature.interfaces.COnSelectCertFileListener;
|
|
|
+import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
|
|
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.util.UUID;
|
|
|
+
|
|
|
+
|
|
|
+public class CreateCertificateDigitalDialog extends BottomSheetDialogFragment implements View.OnClickListener {
|
|
|
+
|
|
|
+ private AppCompatTextView tvTitle;
|
|
|
+
|
|
|
+ private AppCompatImageView ivClose;
|
|
|
+
|
|
|
+ private CEditText etName;
|
|
|
+
|
|
|
+ private CEditText etGrantor;
|
|
|
+
|
|
|
+ private CEditText etSectoral;
|
|
|
+
|
|
|
+ private CEditText etEmail;
|
|
|
+
|
|
|
+ private CEditText etCountryArea;
|
|
|
+
|
|
|
+ private Switch swContinuous;
|
|
|
+
|
|
|
+ private AppCompatButton btnOk;
|
|
|
+
|
|
|
+ private ViewSwitcher switcher;
|
|
|
+
|
|
|
+ private AppCompatTextView tvSaveAddress;
|
|
|
+
|
|
|
+ private LinearLayout llSaveAddress;
|
|
|
+
|
|
|
+ private CEditText etPassword;
|
|
|
+
|
|
|
+ private CEditText etConfirmPassword;
|
|
|
+
|
|
|
+ private AppCompatButton btnConfirmCreate;
|
|
|
+
|
|
|
+ private boolean showSaveStatus = false;
|
|
|
+
|
|
|
+ private OnBackPressedCallback callback;
|
|
|
+
|
|
|
+ private String customSavePath;
|
|
|
+
|
|
|
+ private COnSelectCertFileListener selectCertFileListener;
|
|
|
+
|
|
|
+ private ActivityResultLauncher<Intent> selectDirLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
|
|
|
+ if (result.getData() != null && result.getData().getData() != null) {
|
|
|
+ Uri uri = result.getData().getData();
|
|
|
+ CFileUtils.takeUriPermission(getContext(), result.getData().getData());
|
|
|
+ customSavePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + uri.getPath().replace("/tree/primary:", "");
|
|
|
+ tvSaveAddress.setText(getSaveAddress());
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ public static CreateCertificateDigitalDialog newInstance() {
|
|
|
+ Bundle args = new Bundle();
|
|
|
+ CreateCertificateDigitalDialog fragment = new CreateCertificateDigitalDialog();
|
|
|
+ fragment.setArguments(args);
|
|
|
+ return fragment;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
|
+ super.onCreate(savedInstanceState);
|
|
|
+ setStyle(STYLE_NORMAL, R.style.Tools_Base_Theme_BasicBottomSheetDialogStyle_TopCorners);
|
|
|
+ }
|
|
|
+
|
|
|
+ @NonNull
|
|
|
+ @Override
|
|
|
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
|
|
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
|
|
|
+ if (dialog instanceof ComponentDialog) {
|
|
|
+ ComponentDialog componentDialog = (ComponentDialog) dialog;
|
|
|
+ callback = new OnBackPressedCallback(true) {
|
|
|
+ @Override
|
|
|
+ public void handleOnBackPressed() {
|
|
|
+ if (showSaveStatus) {
|
|
|
+ showInfoStatusView();
|
|
|
+ showSaveStatus = false;
|
|
|
+ callback.setEnabled(false);
|
|
|
+ } else {
|
|
|
+ dismiss();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ componentDialog.getOnBackPressedDispatcher().addCallback(callback);
|
|
|
+ }
|
|
|
+ return dialog;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onStart() {
|
|
|
+ super.onStart();
|
|
|
+ BottomSheetBehavior<View> behavior = BottomSheetBehavior.from((View) getView().getParent());
|
|
|
+ CDialogFragmentUtil.setBottomSheetDialogFragmentFullScreen(getDialog(), behavior);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Nullable
|
|
|
+ @Override
|
|
|
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
|
|
+ View view = inflater.inflate(R.layout.tools_sign_create_cert_digital_id_fragment, container, false);
|
|
|
+ tvTitle = view.findViewById(R.id.tv_tool_bar_title);
|
|
|
+ ivClose = view.findViewById(R.id.iv_tool_bar_close);
|
|
|
+ etName = view.findViewById(R.id.et_name);
|
|
|
+ etGrantor = view.findViewById(R.id.et_grantor);
|
|
|
+ etSectoral = view.findViewById(R.id.et_sectoral);
|
|
|
+ etEmail = view.findViewById(R.id.et_email);
|
|
|
+ etCountryArea = view.findViewById(R.id.et_country_area);
|
|
|
+ swContinuous = view.findViewById(R.id.sw_continuous);
|
|
|
+ btnOk = view.findViewById(R.id.btn_ok);
|
|
|
+ switcher = view.findViewById(R.id.view_switcher);
|
|
|
+ tvSaveAddress = view.findViewById(R.id.tv_save_address);
|
|
|
+ llSaveAddress = view.findViewById(R.id.ll_save_address);
|
|
|
+ etPassword = view.findViewById(R.id.et_password);
|
|
|
+ etConfirmPassword = view.findViewById(R.id.et_confirm_password);
|
|
|
+ btnConfirmCreate = view.findViewById(R.id.btn_save);
|
|
|
+ btnOk.setOnClickListener(this);
|
|
|
+ tvSaveAddress.setOnClickListener(this);
|
|
|
+ btnConfirmCreate.setOnClickListener(this);
|
|
|
+ ivClose.setOnClickListener(this);
|
|
|
+ return view;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
|
+ super.onViewCreated(view, savedInstanceState);
|
|
|
+ tvTitle.setText(R.string.tools_new_certificate_digital_id);
|
|
|
+ etName.addTextChangedListener((s, start, before, count) -> {
|
|
|
+ enableConfirmButton();
|
|
|
+ });
|
|
|
+ etGrantor.addTextChangedListener((s, start, before, count) -> {
|
|
|
+ enableConfirmButton();
|
|
|
+ });
|
|
|
+ etEmail.addTextChangedListener((s, start, before, count) -> {
|
|
|
+ enableConfirmButton();
|
|
|
+ });
|
|
|
+ etSectoral.addTextChangedListener((s, start, before, count) -> {
|
|
|
+ enableConfirmButton();
|
|
|
+ });
|
|
|
+ etCountryArea.addTextChangedListener((s, start, before, count) -> {
|
|
|
+ enableConfirmButton();
|
|
|
+ });
|
|
|
+
|
|
|
+ swContinuous.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
|
|
+ llSaveAddress.setVisibility(isChecked ? View.VISIBLE : View.GONE);
|
|
|
+ tvSaveAddress.setText(getSaveAddress());
|
|
|
+ });
|
|
|
+ tvSaveAddress.setText(getSaveAddress());
|
|
|
+ etName.setText("刘小龙");
|
|
|
+ etGrantor.setText("ComPDFKit");
|
|
|
+ etSectoral.setText("CR10");
|
|
|
+ etEmail.setText("xiaolong.liu.work@gmail.com");
|
|
|
+ etCountryArea.setText("China");
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onClick(View v) {
|
|
|
+ if (v.getId() == R.id.btn_ok) {
|
|
|
+ callback.setEnabled(true);
|
|
|
+ showSaveStatusView();
|
|
|
+ showSaveStatus = true;
|
|
|
+ } else if (v.getId() == R.id.iv_tool_bar_close) {
|
|
|
+ dismiss();
|
|
|
+ } else if (v.getId() == R.id.tv_save_address) {
|
|
|
+ selectDirLauncher.launch(CFileUtils.selectSystemDir(true));
|
|
|
+ } else if (v.getId() == R.id.btn_save){
|
|
|
+ String name = etName.getText();
|
|
|
+ String grantor = etGrantor.getText();
|
|
|
+ String sectoral = etSectoral.getText();
|
|
|
+ String email = etEmail.getText();
|
|
|
+ String countryArea = etCountryArea.getText();
|
|
|
+ String password = etPassword.getText();
|
|
|
+ String verifyPassword = etConfirmPassword.getText();
|
|
|
+
|
|
|
+ if (TextUtils.isEmpty(password) || TextUtils.isEmpty(verifyPassword) || !password.equals(verifyPassword)){
|
|
|
+ etPassword.setError(true);
|
|
|
+ etConfirmPassword.setError(true);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ etPassword.setError(false);
|
|
|
+ etConfirmPassword.setError(false);
|
|
|
+
|
|
|
+ CPDFOwnerInfo ownerInfo = new CPDFOwnerInfo();
|
|
|
+ ownerInfo.setCommonName(name);
|
|
|
+ ownerInfo.setOrgnizeUnit(grantor);
|
|
|
+ ownerInfo.setOrgnize(sectoral);
|
|
|
+ ownerInfo.setEmail(email);
|
|
|
+ ownerInfo.setCountry(countryArea);
|
|
|
+ String uuid = UUID.randomUUID().toString();
|
|
|
+
|
|
|
+ String saveDir = getSaveAddress();
|
|
|
+ String fileName = "new_cert_"+ uuid.substring(uuid.length()-4, uuid.length())+".p12";
|
|
|
+ boolean success = CertificateDigitalDatas.generatePKCS12Cert(ownerInfo, etPassword.getText(),
|
|
|
+ saveDir, fileName);
|
|
|
+ if (success){
|
|
|
+ if (selectCertFileListener != null) {
|
|
|
+ selectCertFileListener.certificateFile(new File(saveDir, fileName).getAbsolutePath(), etPassword.getText());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void enableConfirmButton() {
|
|
|
+ String name = etName.getText();
|
|
|
+ String grantor = etGrantor.getText();
|
|
|
+ String sectoral = etSectoral.getText();
|
|
|
+ String email = etEmail.getText();
|
|
|
+ String countryArea = etCountryArea.getText();
|
|
|
+ boolean enable = !TextUtils.isEmpty(name) && !TextUtils.isEmpty(grantor)
|
|
|
+ && !TextUtils.isEmpty(sectoral) && !TextUtils.isEmpty(email) && !TextUtils.isEmpty(countryArea);
|
|
|
+ btnOk.setEnabled(enable);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showSaveStatusView() {
|
|
|
+ switcher.setInAnimation(getContext(), R.anim.tools_slide_in_right);
|
|
|
+ switcher.setOutAnimation(getContext(), R.anim.tools_slide_out_left);
|
|
|
+ switcher.showNext();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void showInfoStatusView() {
|
|
|
+ switcher.setInAnimation(getContext(), R.anim.tools_slide_in_left);
|
|
|
+ switcher.setOutAnimation(getContext(), R.anim.tools_slide_out_right);
|
|
|
+ switcher.showPrevious();
|
|
|
+ }
|
|
|
+
|
|
|
+ private String getSaveAddress() {
|
|
|
+ if (!TextUtils.isEmpty(customSavePath)){
|
|
|
+ return customSavePath;
|
|
|
+ }
|
|
|
+ File file;
|
|
|
+ if (swContinuous.isChecked()) {
|
|
|
+ file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), CFileUtils.ROOT_FOLDER);
|
|
|
+ } else {
|
|
|
+ file = new File(getContext().getCacheDir(), CFileUtils.CACHE_FOLDER);
|
|
|
+ }
|
|
|
+ return file.getAbsolutePath();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void setSelectCertFileListener(COnSelectCertFileListener selectCertFileListener) {
|
|
|
+ this.selectCertFileListener = selectCertFileListener;
|
|
|
+ }
|
|
|
+}
|