nz.Intelx.DroidNetLogin.DroidNetLoginActivity.java Source code

Java tutorial

Introduction

Here is the source code for nz.Intelx.DroidNetLogin.DroidNetLoginActivity.java

Source

package nz.Intelx.DroidNetLogin;

import nz.Intelx.DroidNetLogin.PreferenceListFragment.OnPreferenceAttachedListener;
import nz.ac.auckland.cs.des.C_Block;
import nz.ac.auckland.cs.des.Key_schedule;
import nz.ac.auckland.cs.des.des_encrypt;
import android.net.Uri;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.ToggleButton;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockDialogFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.SherlockListFragment;
import com.viewpagerindicator.TabPageIndicator;
import com.viewpagerindicator.TitleProvider;

public class DroidNetLoginActivity extends SherlockFragmentActivity
        implements OnPreferenceAttachedListener, OnPreferenceChangeListener, OnPreferenceClickListener {
    /** Called when the activity is first created. */

    static final String NET_PREF = "NetloginPref";
    static final String TAG = "AndNetlogin";
    EditText editUsername;
    EditText editPassword;
    String basedir = null;
    static SharedPreferences preferences;
    PreferenceChangeListener preference_listener;
    static SharedPreferences.Editor preferenceEditor;
    static int next = -1;

    //connection codes
    static int LOGGING_IN = 0;
    static int CONNECTED = 1;
    static int DISCONNECTED = 2;
    static int FAILED = 3;
    static int Status = -1;
    static int IP_Usage;
    static boolean Proxy = false;

    //Intents

    static Intent intent;
    Intent intent_update;
    Intent intent_proxy;

    //UI related
    private static final int NUM_ITEMS = 3;
    private MyAdapter mAdapter;
    private ViewPager mPager;
    public ActionBar mActionBar;
    private EditText usernameEdit;
    private EditText passwordEdit;

    //Options
    public static int Login_Option;
    public static boolean Debug_Option;
    public static boolean Proxy_Option;

    @Override
    public void onResume() {
        super.onResume();
        preferences.registerOnSharedPreferenceChangeListener(preference_listener);
        if (!Service_Running()
                && (preferences.getBoolean("Proxy", false) || preferences.getInt("Status", 5) == 2)) {
            preferenceEditor.putInt("Status", 3);
            preferenceEditor.commit();
            intent.putExtra("debug_option", Debug_Option);
            intent.putExtra("action", 4);
            startService(intent);
        }

        updateUI();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        preference_listener = new PreferenceChangeListener();
        preferences = getSharedPreferences(NET_PREF, 0);
        intent = new Intent(this, NetloginController.class);
        preferenceEditor = preferences.edit();

        //Setup UI
        try {
            setContentView(R.layout.main);
            mActionBar = getSupportActionBar();
            mAdapter = new MyAdapter(getSupportFragmentManager());
            mPager = (ViewPager) findViewById(R.id.pager);
            mPager.setAdapter(mAdapter);
            mPager.setOffscreenPageLimit(2);
            TabPageIndicator tabIndicator = (TabPageIndicator) findViewById(R.id.indicator);
            tabIndicator.setViewPager(mPager);

        } catch (Exception e) {
            Log.e("ViewPager", e.toString());
        }

        //initial check for root and iptables

        File f = new File("/system/xbin/iptables");
        if (!f.exists()) {
            f = new File("/system/bin/iptables");
            if (!f.exists()) {
                alert("Please install Iptables from the <a href = 'market://details?id=com.mgranja.iptables'>Android Play Market</a>.",
                        this);
            }
        }

        f = new File("/system/xbin/su");
        if (!f.exists()) {
            f = new File("/system/bin/su");
            if (!f.exists()) {
                alert("Your device must be rooted.", this);
            }
        }

        try {
            basedir = getBaseContext().getFilesDir().getAbsolutePath();
        } catch (Exception e) {
            e.printStackTrace();
            alert("cannot get application location", this);
        }

        copyfile("redsocks");
        copyfile("proxy.sh");
        copyfile("redirect.sh");

    }

    public void copyfile(String file) {

        String of = file;
        File f = new File(of);

        if (!f.exists()) {
            try {
                InputStream in = getAssets().open(file);
                FileOutputStream out = getBaseContext().openFileOutput(of, MODE_PRIVATE);

                byte[] buf = new byte[1024];
                int len;
                while ((len = in.read(buf)) > 0) {
                    out.write(buf, 0, len);
                }
                out.close();
                in.close();
                Runtime.getRuntime().exec("chmod 700 " + basedir + "/" + of);
            } catch (IOException e) {
            }
        }
    }

    public void alert(String msg, Activity a) {

        final Activity act = a;
        final AlertDialog builder = new AlertDialog.Builder(a).setMessage(Html.fromHtml(msg)).setCancelable(false)
                .setNegativeButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        if (act != null)
                            act.finish();
                        else
                            dialog.cancel();
                    }
                }).show();
        ((TextView) builder.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
    }

    protected void onPause() {
        super.onPause();
        //unregisterReceiver(broadcastReceiver);
        preferences.unregisterOnSharedPreferenceChangeListener(preference_listener);
    }

    private void updateUI() {

        LoginFragment Login_Fragment = (LoginFragment) getSupportFragmentManager()
                .findFragmentByTag("android:switcher:" + R.id.pager + ":0");

        if (Login_Fragment != null && Login_Fragment.getView() != null) {
            TextView t = (TextView) Login_Fragment.getActivity().findViewById(R.id.Status);
            TextView t2 = (TextView) Login_Fragment.getActivity().findViewById(R.id.Usage);
            TextView t3 = (TextView) Login_Fragment.getActivity().findViewById(R.id.proxy_status);
            ToggleButton b = (ToggleButton) Login_Fragment.getActivity().findViewById(R.id.Auto);

            Status = preferences.getInt("Status", -1);
            Proxy = preferences.getBoolean("Proxy", false);
            IP_Usage = preferences.getInt("IP_Usage", 0);

            switch (Status) {
            case 1:
                t.setText("Status: Logging in");
                break;
            case 2:
                t.setText("Status: Connected!");
                break;
            case 3:
                t.setText("Status: Disconnected");
                break;
            case 4:
                t.setText("Status: Error");
                break;
            }

            BigDecimal Usage = new BigDecimal(IP_Usage);

            t2.setText("Usage: " + Usage.divide(new BigDecimal(1000)) + " MB");

            if (Proxy) {
                t3.setText("Proxy: Started");
            } else {
                t3.setText("Proxy: Stopped");
            }

            if (Proxy_Option) {
                if (Status == 2 && Proxy == true) {
                    b.setChecked(true);
                } else {
                    b.setChecked(false);
                }
            } else {
                if (Status == 2) {
                    b.setChecked(true);
                } else {
                    b.setChecked(false);
                }
            }

        }
    }

    public class PreferenceChangeListener implements OnSharedPreferenceChangeListener {

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
            updateUI();
        }
    }

    //Workaround to make sure keyboard is hidden after focus away from textbox
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        View v = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(event);

        if (v instanceof EditText) {
            View w = getCurrentFocus();
            int scrcoords[] = new int[2];
            w.getLocationOnScreen(scrcoords);
            float x = event.getRawX() + w.getLeft() - scrcoords[0];
            float y = event.getRawY() + w.getTop() - scrcoords[1];

            Log.d("Activity",
                    "Touch event " + event.getRawX() + "," + event.getRawY() + " " + x + "," + y + " rect "
                            + w.getLeft() + "," + w.getTop() + "," + w.getRight() + "," + w.getBottom() + " coords "
                            + scrcoords[0] + "," + scrcoords[1]);
            if (event.getAction() == MotionEvent.ACTION_UP
                    && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) {

                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
            }
        }
        return ret;
    }

    public class MyAdapter extends FragmentPagerAdapter implements TitleProvider {
        PreferenceListFragment[] fragments;
        String[] titles;

        public MyAdapter(FragmentManager fm) {
            super(fm);

            titles = new String[3];
            titles[0] = getString(R.string.title_login);
            titles[1] = getString(R.string.title_options);
            titles[2] = getString(R.string.title_about);

        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            if (position == 0) {
                return new LoginFragment();
            } else if (position == 1) {
                return PreferenceListFragment.newInstance(R.layout.fragment_options);
            } else if (position == 2) {
                return new AboutFragment();
            }
            return null;
        }

        @Override
        public String getTitle(int position) {
            // TODO Auto-generated method stub
            return titles[position];
        }
    }

    private boolean Service_Running() {
        String Service = getString(R.string.app_id) + ".NetloginController";
        ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
            if (Service.equals(service.service.getClassName())) {
                return true;
            }
        }
        return false;
    }

    //This defines the fragment of the about page
    public static class AboutFragment extends SherlockListFragment {
        Context activity = this.getActivity();
        private static String[] about_list = new String[] { "About DroidNetLogin", "License", "Donate" };

        private ArrayAdapter<String> listAdapter;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View v = inflater.inflate(R.layout.fragment_about, container, false);
            setupListAdapter();

            return v;
        }

        private void setupListAdapter() {
            listAdapter = new ArrayAdapter<String>(this.getSherlockActivity(), R.layout.list_item, about_list);
            setListAdapter(listAdapter);

        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            super.onListItemClick(l, v, position, id);

            switch (position) {

            case 0:
                showDialog(position);
                break;
            case 1:
                showDialog(position);
                break;
            case 2:
                showDialog(position);
                break;
            }
        }

        void showDialog(int position) {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            SherlockDialogFragment newFragment = MyDialogFragment.newInstance(position);
            newFragment.show(ft, "dialog");

        }

    }

    public static class MyDialogFragment extends SherlockDialogFragment {
        int type;

        static MyDialogFragment newInstance(int type) {
            MyDialogFragment f = new MyDialogFragment();

            // Supply num input as an argument.
            Bundle args = new Bundle();
            args.putInt("type", type);
            f.setArguments(args);

            return f;
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            type = getArguments().getInt("type");
            setStyle(SherlockDialogFragment.STYLE_NORMAL, R.style.Theme_Light_Dialog);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View v = inflater.inflate(R.layout.fragment_dialog, container, false);
            View tv = v.findViewById(R.id.dialog);
            //View iv = v.findViewById(R.id.DonateButton);
            LinearLayout lv = (LinearLayout) v.findViewById(R.id.dialog_layout);

            switch (type) {
            case 0:
                getDialog().setTitle("About");
                ((TextView) tv).setText(getString(R.string.about_DroidNetLogin));
                break;
            case 1:
                getDialog().setTitle("License");
                ((TextView) tv).setText(getString(R.string.about_license));
                break;
            case 2:
                getDialog().setTitle("Donate");
                ((TextView) tv).setText(getString(R.string.about_donate));

                ImageButton iv = new ImageButton(getActivity());
                iv.setBackgroundResource(R.drawable.donate);
                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
                        LayoutParams.WRAP_CONTENT);
                lp.setMargins(10, 10, 10, 10);
                iv.setLayoutParams(lp);

                iv.setOnClickListener(new OnClickListener() {
                    public void onClick(View iv) {
                        Intent intent = new Intent(Intent.ACTION_VIEW);
                        intent.setData(Uri.parse("http://www.google.com"));
                        startActivity(intent);
                    }
                });

                lv.addView(iv);
                break;

            }

            this.getDialog().setCanceledOnTouchOutside(true);
            ((TextView) tv).setMovementMethod(LinkMovementMethod.getInstance());

            return v;
        }
    }

    //This defines the fragment of the login page 
    public static class LoginFragment extends Fragment {
        EditText editUsername;
        EditText editPassword;

        public LoginFragment newInstance() {
            LoginFragment l = new LoginFragment();
            return l;
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            View v = inflater.inflate(R.layout.fragment_login, container, false);
            TextView t = (TextView) v.findViewById(R.id.Status);
            TextView t2 = (TextView) v.findViewById(R.id.Usage);
            TextView t3 = (TextView) v.findViewById(R.id.proxy_status);
            ToggleButton b = (ToggleButton) v.findViewById(R.id.Auto);

            Status = preferences.getInt("Status", -1);
            Proxy = preferences.getBoolean("Proxy", false);
            IP_Usage = preferences.getInt("IP_Usage", 0);

            switch (Status) {
            case 1:
                t.setText("Status: Logging in");
                break;
            case 2:
                t.setText("Status: Connected!");
                break;
            case 3:
                t.setText("Status: Disconnected");
                break;
            case 4:
                t.setText("Status: Error");
                break;
            }

            BigDecimal Usage = new BigDecimal(IP_Usage);

            t2.setText("Usage: " + Usage.divide(new BigDecimal(1000)) + " MB");

            if (Proxy) {
                t3.setText("Proxy: Started");
            } else {
                t3.setText("Proxy: Stopped");
            }

            if (Proxy_Option) {
                if (Status == 2 && Proxy == true) {
                    b.setChecked(true);
                } else {
                    b.setChecked(false);
                }
            } else {
                if (Status == 2) {
                    b.setChecked(true);
                } else {
                    b.setChecked(false);
                }
            }

            //Restoring saved username and password

            String encrypted = preferences.getString("password", "");
            String username = preferences.getString("username", "");
            String password = "";

            if (encrypted != "") {
                password = decrypt_pass(encrypted, username);
            }

            editUsername = (EditText) v.findViewById(R.id.usernameEdit);
            editUsername.setText(username);
            editPassword = (EditText) v.findViewById(R.id.passwordEdit);
            editPassword.setText(password);

            final ToggleButton b5 = (ToggleButton) v.findViewById(R.id.Auto);
            b5.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (b5.isChecked()) {
                        if (true) {
                            intent.putExtra("action", 5);

                            //let Controller know what to do based on the options selected
                            intent.putExtra("debug_option", Debug_Option);
                            intent.putExtra("proxy_option", Proxy_Option);
                            preferenceEditor.putString("username", editUsername.getText().toString());
                            preferenceEditor.putString("password", editPassword.getText().toString());
                            preferenceEditor.commit();
                            LoginFragment.this.getActivity().startService(intent);
                        }
                    } else {
                        intent.putExtra("action", 6);
                        LoginFragment.this.getActivity().startService(intent);
                    }
                }

            });

            return v;
        }

        @Override
        public void onStop() {
            super.onStop();
            String password;
            String encrypted;
            String username;
            //Storing or clearing username and password fields depending on option selected
            switch (Login_Option) {
            case 0:
                preferenceEditor.putString("username", "");
                preferenceEditor.putString("password", "");
                preferenceEditor.commit();
                break;
            case 1:
                preferenceEditor.putString("username", editUsername.getText().toString());
                preferenceEditor.putString("password", "");
                preferenceEditor.commit();
                break;
            case 2:
                username = editUsername.getText().toString();
                password = editPassword.getText().toString();
                encrypted = encrypt_pass(password, username);
                preferenceEditor.putString("username", username);
                preferenceEditor.putString("password", encrypted);
                preferenceEditor.commit();
                break;

            }
        }

        private String encrypt_pass(String pass, String key) {

            C_Block block[];
            String code = "";
            int i;
            Key_schedule schedule = new Key_schedule(key);
            des_encrypt encryptor = new des_encrypt(pass += 1);
            encryptor.des_cbc_encrypt(schedule);
            block = encryptor.get_input_C_Block();

            for (i = 0; i < block.length; i++)
                code += block[i].toHexString();
            return code;

        }

        private String decrypt_pass(String code, String key) {

            String pass = "";

            //split code in to groups of 16 hex digits as required by hex to C_Block

            String[] splitLine = new String[(code.length() + 15) / 16];

            if (splitLine.length > 0)

            {
                for (int index = 0, len = splitLine.length - 1, lineIndex = 0; index < len; index++)

                    splitLine[index] = code.substring(lineIndex, lineIndex += 16);

                splitLine[splitLine.length - 1] = code.substring(splitLine.length * 16 - 16);
            }

            //convert string hex to byte []
            byte[] temp_byte = new byte[8];
            byte[] decrypted = new byte[splitLine.length * 8];
            //C_Block block = new C_Block();
            for (int i = 0; i < splitLine.length; i++) {
                try {
                    C_Block block = new C_Block(splitLine[i], 16);
                    temp_byte = block.data;
                } catch (NumberFormatException e) {
                    return "";
                }
                System.arraycopy(temp_byte, 0, decrypted, i * 8, 8);
            }

            //passing the byte[] to the decryptor             
            des_encrypt decryptor;
            byte[] decrypted_all;
            Key_schedule schedule = new Key_schedule(key);
            ArrayList<String> pass_array = new ArrayList<String>();

            decryptor = new des_encrypt(decrypted);
            decryptor.des_cbc_decrypt(schedule);
            decrypted = decryptor.get_input();
            pass = new String(decrypted).trim();

            return pass;

        }

    }

    @Override
    public void onPreferenceAttached(PreferenceScreen root, int xmlId) {

        if (root == null)
            return; //for whatever reason in very rare cases this is null              
        updatePreference(root.getSharedPreferences());

        //registering the listeners to the preference screen
        root.findPreference("login_preference").setOnPreferenceChangeListener(this);
        root.findPreference("debug_preference").setOnPreferenceChangeListener(this);
        root.findPreference("proxy_preference").setOnPreferenceChangeListener(this);
        root.findPreference("manual_login").setOnPreferenceClickListener(this);
        root.findPreference("manual_logout").setOnPreferenceClickListener(this);
        root.findPreference("manual_startProxy").setOnPreferenceClickListener(this);
        root.findPreference("manual_stopProxy").setOnPreferenceClickListener(this);

        //match summary for Login list preference to selected preference
        ListPreference login_preference = (ListPreference) root.findPreference("login_preference");
        CharSequence Login_Summary = login_preference.getEntry();
        login_preference.setSummary(Login_Summary);

    }

    @Override
    public boolean onPreferenceChange(Preference pref, Object newValue) {

        //match summary for Login list preference to selected preference

        if (pref.getKey().equals("login_preference")) {
            ListPreference login_preference = (ListPreference) pref;
            login_preference.setValue((String) newValue);
            CharSequence Login_Summary = login_preference.getEntry();
            login_preference.setSummary(Login_Summary);
        }
        if (pref.getKey().equals("debug_preference")) {
            CheckBoxPreference debug_preference = (CheckBoxPreference) pref;
            debug_preference.setChecked((Boolean) newValue);
        }
        if (pref.getKey().equals("proxy_preference")) {
            CheckBoxPreference proxy_preference = (CheckBoxPreference) pref;
            proxy_preference.setChecked((Boolean) newValue);
        }
        updatePreference(pref.getSharedPreferences());
        return true;
    }

    @Override
    public boolean onPreferenceClick(Preference pref) {
        if (pref.getKey().equals("manual_login")) {
            intent.putExtra("debug_option", Debug_Option);
            intent.putExtra("proxy_option", Proxy_Option);
            LoginFragment Login_Fragment = (LoginFragment) getSupportFragmentManager()
                    .findFragmentByTag("android:switcher:" + R.id.pager + ":0");
            EditText usernameEdit = (EditText) Login_Fragment.getActivity().findViewById(R.id.usernameEdit);
            EditText passwordEdit = (EditText) Login_Fragment.getActivity().findViewById(R.id.passwordEdit);

            SharedPreferences.Editor preferenceEditor = preferences.edit();
            preferenceEditor.putString("username", usernameEdit.getText().toString());
            preferenceEditor.putString("password", passwordEdit.getText().toString());
            preferenceEditor.commit();
            intent.putExtra("action", 1);
            startService(intent);
        } else if (pref.getKey().equals("manual_logout")) {
            intent.putExtra("action", 2);
            startService(intent);
        } else if (pref.getKey().equals("manual_startProxy")) {
            intent.putExtra("debug_option", Debug_Option);
            intent.putExtra("action", 3);
            startService(intent);
        } else if (pref.getKey().equals("manual_stopProxy")) {
            intent.putExtra("debug_option", Debug_Option);
            intent.putExtra("action", 4);
            startService(intent);
        }
        return true;
    }

    private void updatePreference(SharedPreferences pref) {

        Debug_Option = pref.getBoolean("debug_preference", false);
        Proxy_Option = pref.getBoolean("proxy_preference", true);

        String Login_Option_String = pref.getString("login_preference", "1");
        Login_Option = Integer.parseInt(Login_Option_String);

    }

}