com.tinfoil.sms.settings.UserKeySettings.java Source code

Java tutorial

Introduction

Here is the source code for com.tinfoil.sms.settings.UserKeySettings.java

Source

/** 
 * Copyright (C) 2013 Jonathan Gillett, Joseph Heron
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.tinfoil.sms.settings;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.NavUtils;
import android.text.InputType;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bugsense.trace.BugSenseHandler;
import com.tinfoil.sms.R;
import com.tinfoil.sms.crypto.KeyExchange;
import com.tinfoil.sms.crypto.KeyGenerator;
import com.tinfoil.sms.dataStructures.Number;
import com.tinfoil.sms.dataStructures.TrustedContact;
import com.tinfoil.sms.dataStructures.User;
import com.tinfoil.sms.database.DBAccessor;
import com.tinfoil.sms.utility.SMSUtility;

public class UserKeySettings extends Activity {

    private ArrayList<TrustedContact> tc;
    private AlertDialog popup_alert;
    private AutoCompleteTextView phoneBook;

    public static final String path = "/keys";
    public static final String file = "exchange.txt";

    private DBAccessor dba;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.user_key_settings);

        setupActionBar();

        dba = new DBAccessor(this);
        TextView keyView = (TextView) findViewById(R.id.public_key);

        // Check if the user is null
        if (SMSUtility.user == null) {
            SMSUtility.user = dba.getUserRow();
        }

        //Check if the user is still null (never set in db)   
        if (SMSUtility.user == null) {
            // Generate the user's public key
            KeyGenerator keyGen = new KeyGenerator();

            SMSUtility.user = new User(keyGen.generatePubKey(), keyGen.generatePriKey());

            //Set the user's 
            dba.setUser(SMSUtility.user);
        }

        keyView.setText(new String(SMSUtility.user.getPublicKey()));
    }

    /*@Override
    public boolean onCreateOptionsMenu(Menu menu) {
       // Inflate the menu; this adds items to the action bar if it is present.
       getMenuInflater().inflate(R.menu.user_key_settings, menu);
       return true;
    }*/

    public void exportKey(View view) {
        if (SMSUtility.isMediaWritable()) {
            phoneBook = new AutoCompleteTextView(this);
            List<String> contact = null;
            if (tc == null) {
                //Do in thread.
                tc = dba.getAllRows(DBAccessor.ALL);
            }

            if (tc != null) {
                if (contact == null) {
                    contact = SMSUtility.contactDisplayMaker(tc);
                }
            } else {
                contact = null;
            }
            final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this.getBaseContext(),
                    R.layout.auto_complete_list_item, contact);

            phoneBook.setAdapter(adapter);

            final AlertDialog.Builder popup_builder = new AlertDialog.Builder(this);
            popup_builder.setTitle(R.string.import_contacts_title).setCancelable(true).setView(phoneBook)
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                        public void onClick(final DialogInterface dialog, final int which) {

                            String[] contactInfo = SMSUtility.parseAutoComplete(phoneBook.getText().toString());
                            //String number = null;

                            boolean invalid = false;
                            if (contactInfo != null) {
                                if (contactInfo[0] == null) {
                                    contactInfo[0] = contactInfo[1];
                                }

                                final Number number = dba.getNumber(contactInfo[1]);

                                if (number != null) {
                                    AlertDialog.Builder builder = new AlertDialog.Builder(UserKeySettings.this);
                                    LinearLayout linearLayout = new LinearLayout(UserKeySettings.this);
                                    linearLayout.setOrientation(LinearLayout.VERTICAL);

                                    final EditText sharedSecret1 = new EditText(UserKeySettings.this);
                                    sharedSecret1
                                            .setHint(UserKeySettings.this.getString(R.string.shared_secret_hint_1));
                                    sharedSecret1.setMaxLines(EditNumber.SHARED_INFO_MAX);
                                    sharedSecret1.setInputType(InputType.TYPE_CLASS_TEXT);
                                    linearLayout.addView(sharedSecret1);

                                    final EditText sharedSecret2 = new EditText(UserKeySettings.this);
                                    sharedSecret2
                                            .setHint(UserKeySettings.this.getString(R.string.shared_secret_hint_2));
                                    sharedSecret2.setMaxLines(EditNumber.SHARED_INFO_MAX);
                                    sharedSecret2.setInputType(InputType.TYPE_CLASS_TEXT);
                                    linearLayout.addView(sharedSecret2);

                                    builder.setMessage(UserKeySettings.this.getString(R.string.set_shared_secrets)
                                            + " " + contactInfo[0] + ", " + number.getNumber())
                                            .setTitle(R.string.set_shared_secrets_title).setCancelable(true)
                                            .setPositiveButton(R.string.save,
                                                    new DialogInterface.OnClickListener() {
                                                        @Override
                                                        public void onClick(DialogInterface dialog, int id) {
                                                            //Save the shared secrets

                                                            String s1 = sharedSecret1.getText().toString();
                                                            String s2 = sharedSecret2.getText().toString();
                                                            if (SMSUtility.checksharedSecret(s1)
                                                                    && SMSUtility.checksharedSecret(s2)) {
                                                                number.setSharedInfo1(s1);
                                                                number.setSharedInfo2(s2);
                                                                dba.updateNumberRow(number, number.getNumber(),
                                                                        number.getId());

                                                                number.setInitiator(true);
                                                                dba.updateInitiator(number);

                                                                //TODO add check for shared secrets
                                                                String keyExchangeMessage = KeyExchange.sign(number,
                                                                        dba, SMSUtility.user);

                                                                writeToFile(number.getNumber(), keyExchangeMessage);

                                                                Toast.makeText(UserKeySettings.this,
                                                                        UserKeySettings.this
                                                                                .getString(R.string.written_path)
                                                                                + " " + path + "/"
                                                                                + number.getNumber() + "_" + file,
                                                                        Toast.LENGTH_SHORT).show();

                                                            } else {
                                                                Toast.makeText(UserKeySettings.this,
                                                                        R.string.invalid_secrets, Toast.LENGTH_LONG)
                                                                        .show();
                                                            }
                                                        }
                                                    })
                                            .setNegativeButton(android.R.string.cancel,
                                                    new DialogInterface.OnClickListener() {
                                                        @Override
                                                        public void onClick(DialogInterface arg0, int arg1) {
                                                            //Cancel the key exchange
                                                            Toast.makeText(UserKeySettings.this,
                                                                    R.string.key_exchange_cancelled,
                                                                    Toast.LENGTH_LONG).show();
                                                        }
                                                    });
                                    AlertDialog alert = builder.create();

                                    alert.setView(linearLayout);
                                    alert.show();
                                } else {
                                    invalid = true;
                                }
                            } else {
                                invalid = true;
                            }

                            if (invalid) {
                                Toast.makeText(UserKeySettings.this, R.string.invalid_number_message,
                                        Toast.LENGTH_LONG).show();
                            }
                        }
                    });

            popup_alert = popup_builder.create();
            popup_alert.show();

            //getExternalFilesDir(null);
        }
    }

    public static void writeToFile(String name, String text) {
        File root = Environment.getExternalStorageDirectory();

        File keys = new File(root.getAbsolutePath() + path);
        keys.mkdirs();

        File pubKey = new File(keys, name + "_" + file);

        try {
            FileOutputStream f = new FileOutputStream(pubKey);
            PrintWriter pw = new PrintWriter(f);
            pw.println(text);
            pw.flush();
            pw.close();
            f.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            BugSenseHandler.sendExceptionMessage("Type", "Export Public Key Not Found Error", e);
        } catch (IOException e) {
            e.printStackTrace();
            BugSenseHandler.sendExceptionMessage("Type", "Export Public Key Error", e);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {

        final MenuInflater inflater = this.getMenuInflater();
        inflater.inflate(R.menu.remove_contacts_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(final MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            // This ID represents the Home or Up button. In the case of this
            // activity, the Up button is shown. Use NavUtils to allow users
            // to navigate up one level in the application structure. For
            // more details, see the Navigation pattern on Android Design:
            //
            // http://developer.android.com/design/patterns/navigation.html#up-vs-back
            //
            NavUtils.navigateUpFromSameTask(this);
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }

    }

    /**
    * Set up the {@link android.app.ActionBar}, if the API is available.
    */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private void setupActionBar() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            getActionBar().setDisplayHomeAsUpEnabled(true);
        }
    }
}