/* Tibisay Movil Copyright (C) 2013 Antonio Araujo (aaraujo@cenditel.gob.ve), Jose Ruiz (jruiz@cenditel.gob.ve), Fundacion Centro Nacional de Desarrollo e Investigacion en Tecnologias Libres - CENDITEL. La Fundación CENDITEL concede permiso para usar, copiar, distribuir y/o modificar este programa, reconociendo el derecho que la humanidad posee al libre acceso al conocimiento, bajo los términos de la licencia de software GPL versión 2.0 de la Free Software Foundation. Este programa se distribuye con la esperanza de que sea util, pero SIN NINGUNA GARANTIA; tampoco las implicitas garantias de MERCANTILIDAD o ADECUACION A UN PROPOSITO PARTICULAR. Para mayor información sobre los términos de la licencia ver el archivo llamado "gpl-2.0.txt" en ingles. */ package ve.gob.cenditel.tibisaymovil; import android.app.Activity; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnDismissListener; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import android.widget.AdapterView.OnItemClickListener; import android.widget.LinearLayout.LayoutParams; public class CertificateRepositoryActivity extends Activity implements OnClickListener, OnItemClickListener { public DirectKeyChain keyChain; public KeyChainView viewHolder; protected int requestCode; protected int resultCode; private int numChecks; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.certificate_zone); LinearLayout certZone = (LinearLayout) findViewById(R.id.certificate_zone); this.viewHolder = new KeyChainView(this, certZone); this.prepareKeyChain(); this.viewHolder.delete.setEnabled(this.numChecks>0); } //prepara el llavero private void prepareKeyChain() { this.keyChain = DirectKeyChain.getInstance(); this.keyChain.setListView(this.viewHolder.aliases); this.keyChain.setMasterActivity((Activity) this); this.keyChain.setButtonsKeyStoreStatus(false); this.keyChain.choosePrivateKeyAlias(); // try { // if (this.viewHolder.aliases.getAdapter()!=null) // this.viewHolder.aliases.setAdapter(new DirectCertificateAdapter(this.keyChain, CertificateRepositoryActivity.this)); // } catch (KeystoreException e) { // Toast.makeText(CertificateRepositoryActivity.this, R.string.error_unknown, Toast.LENGTH_LONG).show(); // //throw new RuntimeException(e); // } } //On click listener for button1 final OnClickListener mGlobal_OnClickListener = new OnClickListener() { public void onClick(final View v) { switch(v.getId()) { case R.id.cert_chooser_install_button: Toast.makeText(CertificateRepositoryActivity.this, "install", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(CertificateRepositoryActivity.this.getBaseContext(), PKCS12FilePickerActivity.class); startActivity(intent); break; } } }; @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == ActivityResult.IMPORT_CERTIFICATE && resultCode == Activity.RESULT_OK) { this.launchPasswordDialog(data); } if (resultCode == RESULT_OK) { //startActivity(new Intent(Intent.ACTION_VIEW, data)); Log.d("CertificateRepositoryActivity: ", "onActivityResult -> RESULT_OK"); } } @Override public void onClick(View view) { switch (view.getId()) { case R.id.cert_chooser_install_button: if(this.keyChain.isButtonsKeyStoreStatus()) { Intent intent = new Intent(this, PKCS12FilePickerActivity.class); ((Activity) this).startActivityForResult(intent, ActivityResult.IMPORT_CERTIFICATE); } else { Toast.makeText(CertificateRepositoryActivity.this, R.string.no_access_to_keystore, Toast.LENGTH_LONG).show(); } break; case R.id.button_delete: if (this.numChecks>0) deleteSelectedCertificates(); break; case R.id.button_open: if(this.keyChain.isButtonsKeyStoreStatus()) { //Crear nuevo almacen. this.keyChain.createKeystoreAndChoosePrivateKeyAlias(); } else { Toast.makeText(CertificateRepositoryActivity.this, R.string.no_access_to_keystore, Toast.LENGTH_LONG).show(); } break; case R.id.change_password: if(this.keyChain.isButtonsKeyStoreStatus()) { this.changePassword(); } else { Toast.makeText(CertificateRepositoryActivity.this, R.string.no_access_to_keystore, Toast.LENGTH_LONG).show(); } break; } } public void changePassword() { final PasswordConfirmationDialog dialog = new PasswordConfirmationDialog((Activity) this, R.string.keystore_new_password); dialog.setAcceptListener(new OnClickListener() { @Override public void onClick(View v) { String newPassword = dialog.getPassword(); dialog.dismiss(); try { CertificateRepositoryActivity.this.keyChain.saveKeystore(newPassword); Toast.makeText(CertificateRepositoryActivity.this, R.string.password_change_success, Toast.LENGTH_LONG).show(); } catch (OutOfSpaceError e) { Toast.makeText(CertificateRepositoryActivity.this, R.string.error_no_space, Toast.LENGTH_LONG).show(); } catch (KeystoreException e) { Toast.makeText(CertificateRepositoryActivity.this, R.string.error_unknown, Toast.LENGTH_LONG).show(); //throw new RuntimeException(e); } } }); dialog.show(); } @Override public void onItemClick(AdapterView parent, View view, int item, long id) { this.updateCheckedNumber(); this.updateButtons(); } private void updateButtons() { this.viewHolder.delete.setEnabled(this.numChecks>0); //this.viewHolder.accept.setEnabled(this.numChecks==1); Drawable icon = this.viewHolder.delete.getCompoundDrawables()[1]; if (this.numChecks>0) icon.setAlpha(255); else icon.setAlpha(127); } private void updateCheckedNumber() { SparseBooleanArray checkedItems = this.viewHolder.aliases.getCheckedItemPositions(); int count = 0; for (int i = 0; i < checkedItems.size(); i++) { if (checkedItems.valueAt(i)) count++; } this.numChecks = count; } private void deleteSelectedCertificates() { SparseBooleanArray checkedItems = this.viewHolder.aliases.getCheckedItemPositions(); for (int i = 0; i < checkedItems.size(); i++) { if(checkedItems.valueAt(i) == true){ try { int position = checkedItems.keyAt(i); this.keyChain.deleteCertificate( (String) this.viewHolder.aliases.getItemAtPosition(position)); } catch (KeystoreException e) { e.printStackTrace(); } } } //Refresh adapter. NotifyDataSetChange didnt work. try { CertificateRepositoryActivity.this.viewHolder.aliases.setAdapter( new DirectCertificateAdapter(CertificateRepositoryActivity.this.keyChain, this)); } catch (KeystoreException e) { e.printStackTrace(); } this.updateCheckedNumber(); this.updateButtons(); try { this.keyChain.saveKeystore(); } catch (KeystoreException e) { } catch (OutOfSpaceError e) { } } private void launchPasswordDialog(final Intent data) { final PasswordDialog dialog = new PasswordDialog(this, R.string.certificate_password, false); dialog.setAcceptListener(new OnClickListener() { @Override public void onClick(View v) { try { DirectKeyChain direct = DirectKeyChain.getInstance(); int imported = direct.importCertificate(data.getData(), dialog.getPassword()); String text = CertificateRepositoryActivity.this.getResources().getQuantityString(R.plurals.number_imported_certificates, imported, imported); Toast.makeText(CertificateRepositoryActivity.this, text, Toast.LENGTH_LONG).show(); direct.saveKeystore(); direct.refreshAdapter(); } catch (IncorrectPasswordException e) { Toast toast = Toast.makeText(CertificateRepositoryActivity.this, R.string.incorrect_password, Toast.LENGTH_LONG); toast.show(); } catch (Exception e) { Toast toast = Toast.makeText(CertificateRepositoryActivity.this, R.string.error_reading_p12, Toast.LENGTH_LONG); toast.show(); } dialog.dismiss(); CertificateRepositoryActivity.this.requestCode=Integer.MIN_VALUE; CertificateRepositoryActivity.this.resultCode=Integer.MIN_VALUE; } }); dialog.setOnDismissListener(new OnDismissListener(){ @Override public void onDismiss(DialogInterface arg0) { CertificateRepositoryActivity.this.requestCode=Integer.MIN_VALUE; CertificateRepositoryActivity.this.resultCode=Integer.MIN_VALUE; }}); dialog.setOnCancelListener(new OnCancelListener(){ @Override public void onCancel(DialogInterface dialog) { CertificateRepositoryActivity.this.requestCode=Integer.MIN_VALUE; CertificateRepositoryActivity.this.resultCode=Integer.MIN_VALUE; }}); dialog.show(); } /*********************** Otras clases ********************/ private class KeyChainView { public ViewGroup parent; public View generalView; public ListView aliases; public TextView install; // public Button accept; // public Button cancel; public TextView delete; private Context context; private TextView open; private TextView change; private LinearLayout tempLayout; public KeyChainView(Context context, ViewGroup parent) { this.context=context; this.parent=parent; this.tempLayout = new LinearLayout(context); tempLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT)); LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); this.generalView = inflater.inflate(R.layout.certificate_chooser, tempLayout, true); TextView description1 = (TextView) this.generalView.findViewById(R.id.cert_description); description1.setTypeface(Typeface.createFromAsset(this.context.getAssets(), "fonts/Roboto-Medium.ttf"), Typeface.BOLD); this.aliases = (ListView) this.generalView.findViewById(R.id.cert_chooser); this.aliases.setOnItemClickListener(CertificateRepositoryActivity.this); this.install = (TextView) this.generalView.findViewById(R.id.cert_chooser_install_button); this.install.setOnClickListener(CertificateRepositoryActivity.this); this.delete = (TextView) this.generalView.findViewById(R.id.button_delete); this.delete.setOnClickListener(CertificateRepositoryActivity.this); this.open = (TextView) this.generalView.findViewById(R.id.button_open); this.open.setOnClickListener(CertificateRepositoryActivity.this); this.change = (TextView) this.generalView.findViewById(R.id.change_password); this.change.setOnClickListener(CertificateRepositoryActivity.this); /* this.accept = (Button) this.generalView.findViewById(R.id.button_accept); this.cancel = (Button) this.generalView.findViewById(R.id.button_cancel); this.accept.setVisibility(View.GONE); this.cancel.setVisibility(View.GONE);*/ this.parent.addView(tempLayout); } } }