I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
MainActivity.java 10.9 KiB
Newer Older
package net.i2p.android.router;
zzz's avatar
zzz committed

import android.content.ComponentName;
str4d's avatar
str4d committed
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
str4d's avatar
str4d committed
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
str4d's avatar
str4d committed
import net.i2p.android.help.HelpActivity;
str4d's avatar
str4d committed
import net.i2p.android.router.dialog.AboutDialog;
import net.i2p.android.router.dialog.TextResourceDialog;
import net.i2p.android.router.service.IRouterState;
import net.i2p.android.router.service.IRouterStateCallback;
import net.i2p.android.router.service.RouterService;
import net.i2p.android.router.service.State;
str4d's avatar
str4d committed
import net.i2p.android.router.util.Connectivity;
import net.i2p.android.router.util.Util;
str4d's avatar
str4d committed

import java.io.File;
import java.lang.ref.WeakReference;
zzz's avatar
zzz committed

public class MainActivity extends I2PActivityBase implements
        MainFragment.RouterControlListener {
    IRouterState mStateService = null;
    MainFragment mMainFragment = null;
str4d's avatar
str4d committed
    private boolean mAutoStartFromIntent = false;
zzz's avatar
zzz committed
    @Override
    public void onCreate(Bundle savedInstanceState) {
zzz's avatar
zzz committed
        super.onCreate(savedInstanceState);

        // Start with the home view
        if (savedInstanceState == null) {
            mMainFragment = new MainFragment();
            mMainFragment.setArguments(getIntent().getExtras());
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.main_fragment, mMainFragment).commit();
zzz's avatar
zzz committed
        }

        // Open nav drawer if the user has never opened it themselves
        if (!getPref(PREF_NAV_DRAWER_OPENED, false))
            mDrawerLayout.openDrawer(mDrawerList);
zzz's avatar
zzz committed
    }

    protected void onPostCreate(Bundle savedInstanceState) {
        Util.d("Initializing...");
        InitActivities init = new InitActivities(this);
        init.debugStuff();
        init.initialize();
        super.onPostCreate(savedInstanceState);
str4d's avatar
str4d committed
        handleIntents();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        handleIntents();
    }

    private void handleIntents() {
        if (getIntent() == null)
            return;

        Intent intent = getIntent();
        String action = intent.getAction();

        if (action == null)
            return;

        if (action.equals("net.i2p.android.router.START_I2P")) {
    private void autoStart() {
str4d's avatar
str4d committed
            if (Connectivity.isConnected(this)) {
                mAutoStartFromIntent = true;
                onStartRouterClicked();
            } else {
                // Not connected to a network
                // TODO: Notify user
str4d's avatar
str4d committed
            }
        } else {
            // TODO: Notify user
str4d's avatar
str4d committed
        }
zzz's avatar
zzz committed
    }
str4d's avatar
str4d committed
    @Override
    public void onResume() {
        super.onResume();
        if (mStateService != null) {
            try {
                if (mStateService.isStarted()) {
                    // Update for the current state.
                    Util.d("Fetching state.");
                    State curState = mStateService.getState();
str4d's avatar
str4d committed
                    Message msg = mHandler.obtainMessage(STATE_MSG);
                    msg.getData().putParcelable(MSG_DATA, curState);
str4d's avatar
str4d committed
                    mHandler.sendMessage(msg);
                } else {
                    Util.d("StateService not started yet");
str4d's avatar
str4d committed
                }
            } catch (RemoteException e) {}
        }
    }

str4d's avatar
str4d committed
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.activity_main_actions, menu);
str4d's avatar
str4d committed
        inflater.inflate(R.menu.activity_base_actions, menu);
str4d's avatar
str4d committed
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_settings:
            Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
            startActivity(intent);
            return true;

str4d's avatar
str4d committed
        case R.id.menu_about:
            AboutDialog dialog = new AboutDialog();
            dialog.show(getSupportFragmentManager(), "about");
            return true;

str4d's avatar
str4d committed
        case R.id.menu_help:
            Intent hi = new Intent(MainActivity.this, HelpActivity.class);
            startActivity(hi);
            return true;

        case R.id.menu_help_release_notes:
            TextResourceDialog rDdialog = new TextResourceDialog();
            Bundle args = new Bundle();
            args.putString(TextResourceDialog.TEXT_DIALOG_TITLE,
                    getResources().getString(R.string.label_release_notes));
            args.putInt(TextResourceDialog.TEXT_RESOURCE_ID, R.raw.releasenotes_txt);
            rDdialog.setArguments(args);
            rDdialog.show(getSupportFragmentManager(), "release_notes");
str4d's avatar
str4d committed
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onStop() {
        if (mStateService != null) {
            try {
                mStateService.unregisterCallback(mStateCallback);
            } catch (RemoteException e) {}
        }
        if (mTriedBindState)
            unbindService(mStateConnection);
        mTriedBindState = false;
        super.onStop();
    }

    @Override
    protected void onRouterBind(RouterService svc) {
        if (mStateService == null) {
            // Try binding for state updates.
            // Don't auto-create the RouterService.
            Intent intent = new Intent(IRouterState.class.getName());
            intent.setClassName(this, "net.i2p.android.router.service.RouterService");
            mTriedBindState = bindService(intent,
            Util.d("Bind to IRouterState successful: " + mTriedBindState);
    private boolean mTriedBindState;
    private ServiceConnection mStateConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            mStateService = IRouterState.Stub.asInterface(service);
            Util.d("StateService bound");
            try {
                if (mStateService.isStarted()) {
                    mStateService.registerCallback(mStateCallback);
                    // Update for the current state.
                    Util.d("Fetching state.");
                    State curState = mStateService.getState();
                    Message msg = mHandler.obtainMessage(STATE_MSG);
                    msg.getData().putParcelable(MSG_DATA, curState);
                    mHandler.sendMessage(msg);
                } else {
                    // Unbind
                    unbindService(mStateConnection);
                    mStateService = null;
                    mTriedBindState = false;
                }
            } catch (RemoteException e) {
                // In this case the service has crashed before we could even
                // do anything with it; we can count on soon being
                // disconnected (and then reconnected if it can be restarted)
                // so there is no need to do anything here.
            }
        }

        public void onServiceDisconnected(ComponentName className) {
            // This is called when the connection with the service has been
            // unexpectedly disconnected -- that is, its process crashed.
            mStateService = null;
        }
    };

    private IRouterStateCallback mStateCallback = new IRouterStateCallback.Stub() {
        /**
         * This is called by the RouterService regularly to tell us about
         * new states.  Note that IPC calls are dispatched through a thread
         * pool running in each process, so the code executing here will
         * NOT be running in our main thread like most other things -- so,
         * to update the UI, we need to use a Handler to hop over there.
         */
        public void stateChanged(State newState) throws RemoteException {
            Message msg = mHandler.obtainMessage(STATE_MSG);
            msg.getData().putParcelable(MSG_DATA, newState);
            mHandler.sendMessage(msg);
        }
    };

    private static final int STATE_MSG = 1;
    private static final String MSG_DATA = "state";
str4d's avatar
str4d committed
    private Handler mHandler = new StateHandler(new WeakReference<>(this));
    private static class StateHandler extends Handler {
        WeakReference<MainActivity> mReference;

        public StateHandler(WeakReference<MainActivity> reference) {
            mReference = reference;
        }

        private State lastRouterState = null;
        @Override
        public void handleMessage(Message msg) {
str4d's avatar
str4d committed
            MainActivity parent = mReference.get();
            if (parent == null)
                return;

                State state = msg.getData().getParcelable(MSG_DATA);
                if (lastRouterState == null || lastRouterState != state) {
str4d's avatar
str4d committed
                    if (parent.mMainFragment == null)
                        parent.mMainFragment = (MainFragment) parent.getSupportFragmentManager().findFragmentById(R.id.main_fragment);
                    if (parent.mMainFragment != null) {
                        parent.mMainFragment.updateState(state);
str4d's avatar
str4d committed

str4d's avatar
str4d committed
                    if (state == State.RUNNING && parent.mAutoStartFromIntent) {
                        parent.setResult(RESULT_OK);
                        parent.finish();
str4d's avatar
str4d committed
                    }
str4d's avatar
str4d committed
    }
str4d's avatar
str4d committed
    private boolean canStart() {
        RouterService svc = _routerService;
        return (svc == null) || (!_isBound) || svc.canManualStart();
    }

    private boolean canStop() {
        RouterService svc = _routerService;
        return svc != null && _isBound && svc.canManualStop();
    }

    // MainFragment.RouterControlListener

    public boolean shouldShowOnOff() {
str4d's avatar
str4d committed
        return (canStart() && Connectivity.isConnected(this)) || canStop();
str4d's avatar
str4d committed
        String action = getIntent().getAction();
        return (canStop()) ||
                (action != null && action.equals("net.i2p.android.router.START_I2P"));
    }

    public void onStartRouterClicked() {
        RouterService svc = _routerService;
        if(svc != null && _isBound) {
            setPref(PREF_AUTO_START, true);
            svc.manualStart();
        } else {
str4d's avatar
str4d committed
            (new File(Util.getFileDir(this), "wrapper.log")).delete();
            startRouter();
        }
    }

    public boolean onStopRouterClicked() {
        RouterService svc = _routerService;
        if(svc != null && _isBound) {
            setPref(PREF_AUTO_START, false);
            svc.manualQuit();
            return true;
        }
        return false;
    }
zzz's avatar
zzz committed
}