gt:       viewPager = (ViewPager) findViewById(R.id.viewpager);
context: /* (C) 2012 Pragmatic Software
     This Source Code Form is subject to the terms of the Mozilla Public
     License, v. 2.0. If a copy of the MPL was not distributed with this
     file, You can obtain one at http://mozilla.org/MPL/2.0/
   */
  
  package com.googlecode.networklog;
  
  import android.os.Bundle;
  import android.content.Intent;
  import android.os.Handler;
  import android.os.Looper;
  import android.os.Message;
  import android.content.ServiceConnection;
  import android.content.ComponentName;
  import android.content.res.Resources;
  import android.os.Messenger;
  import android.os.RemoteException;
  import android.os.IBinder;
  import android.content.Context;
  import android.app.AlertDialog;
  import android.content.DialogInterface;
  import android.widget.TextView;
  import android.widget.ToggleButton;
  import android.widget.CheckBox;
  import android.view.View;
  import android.view.LayoutInflater;
  import android.util.Log;
  import android.app.ActivityManager;
  import android.app.ActivityManager.RunningServiceInfo;
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentActivity;
  import android.support.v4.app.FragmentManager;
  import android.support.v4.app.FragmentPagerAdapter;
  import android.support.v4.view.ViewPager;
  
  import com.viewpagerindicator.TitlePageIndicator;
  import com.viewpagerindicator.TitleProvider;
  import com.actionbarsherlock.app.SherlockFragmentActivity;
  import com.actionbarsherlock.view.Menu;
  import com.actionbarsherlock.view.MenuItem;
  import com.actionbarsherlock.view.MenuInflater;
  import com.actionbarsherlock.app.ActionBar;
  
  import java.util.Enumeration;
  import java.net.NetworkInterface;
  import java.net.InetAddress;
  import java.net.SocketException;
  import java.util.ArrayList;
  import java.io.File;
  
  public class NetworkLog extends SherlockFragmentActivity {
    public static RetainInstanceData data = null;
  
    public static ViewPager viewPager;
    public final static int PAGE_LOG = 0;
    public final static int PAGE_APP = 1;
    public final static int PAGES    = 2;
  
    public static LogFragment logFragment;
    public static AppFragment appFragment;
  
    public static ToggleButton loggingButton;
    public static TextView statusText;
    public static Settings settings;
    public static Handler handler;
  
    public static String filterTextInclude;
    public static ArrayList<String> filterTextIncludeList = new ArrayList<String>();
    public static boolean filterUidInclude;
    public static boolean filterNameInclude;
    public static boolean filterAddressInclude;
    public static boolean filterPortInclude;
    public static boolean filterInterfaceInclude;
    public static boolean filterProtocolInclude;
  
    public static String filterTextExclude;
    public static ArrayList<String> filterTextExcludeList = new ArrayList<String>();
    public static boolean filterUidExclude;
    public static boolean filterNameExclude;
    public static boolean filterAddressExclude;
    public static boolean filterPortExclude;
    public static boolean filterInterfaceExclude;
    public static boolean filterProtocolExclude;
  
    public static NetworkResolver resolver;
    public static boolean resolveHosts;
    public static boolean resolvePorts;
    public static boolean resolveCopies;
  
    public static boolean startServiceAtStart;
    public static boolean stopServiceAtExit;
  
    public static HistoryLoader history;
    public static FeedbackDialog feedbackDialog;
    public static ExportDialog exportDialog;
    public static ClearLog clearLog;
    public static SelectBlockedApps selectBlockedApps;
    public static SelectToastApps selectToastApps;
  
    public static StatusUpdater statusUpdater;
  
    public static ArrayList<String> localIpAddrs;
  
    public static Messenger service = null;
    public static Messenger messenger = null;
    public static boolean isBound = false;
  
    public static Context context;
    public static Menu menu;
  
    public static InteractiveShell shell;
  
    public static NetworkLog instance;
  
    public static ServiceConnection connection = new ServiceConnection() {
      public void onServiceConnected(ComponentName className, IBinder serv) {
        service = new Messenger(serv);
        isBound = true;
  
        MyLog.d("Attached to service; setting isBound true");
  
        // Register with service
        try {
          Message msg = Message.obtain(null, NetworkLogService.MSG_REGISTER_CLIENT);
          msg.replyTo = messenger;
          service.send(msg);
        } catch(RemoteException e) {
          /* do nothing */
          Log.d("NetworkLog", "RemoteException registering with service", e);
        }
      }
  
      public void onServiceDisconnected(ComponentName className) {
        MyLog.d("Detached from service; setting isBound false");
        service = null;
        isBound = false;
      }
    };
  
    private LogEntry entry;
  
    class IncomingHandler extends Handler {
      @Override
        public void handleMessage(Message msg) {
          if(MyLog.enabled && MyLog.level >= 2) {
            MyLog.d(2, "[client] Received message: " + msg);
          }
  
          switch(msg.what) {
            case NetworkLogService.MSG_BROADCAST_LOG_ENTRY:
              entry = (LogEntry) msg.obj;
              if(MyLog.enabled && MyLog.level >= 2) {
                MyLog.d(2, "Received entry: " + entry);
              }
              logFragment.onNewLogEntry(entry);
              appFragment.onNewLogEntry(entry);
              break;
  
            default:
              super.handleMessage(msg);
          }
        }
    }
  
    void doBindService() {
      MyLog.d("doBindService");
      if(isBound) {
        MyLog.d("Already bound to service; unbinding...");
        doUnbindService();
      }
  
      messenger = new Messenger(new IncomingHandler());
      MyLog.d("Created messenger: " + messenger);
  
      MyLog.d("Binding connection to service: " + connection);
      bindService(new Intent(this, NetworkLogService.class), connection, 0);
      MyLog.d("doBindService done");
    }
  
    void doUnbindService() {
      MyLog.d("doUnbindService");
      if(isBound) {
        if(service != null) {
          try {
            MyLog.d("Unregistering from service; service: " + service + "; messenger: " + messenger);
            Message msg = Message.obtain(null, NetworkLogService.MSG_UNREGISTER_CLIENT);
            msg.replyTo = messenger;
            service.send(msg);
          } catch(RemoteException e) {
            /* do nothing */
            Log.d("NetworkLog", "RemoteException unregistering with service", e);
          }
  
          try {
            MyLog.d("Unbinding connection from service:" + connection);
            unbindService(connection);
          } catch(Exception e) {
            Log.d("NetworkLog", "Ignored unbind exception:", e);
          } finally {
            MyLog.d("Setting isBound false");
            isBound = false;
          }
  
          MyLog.d("doUnbindService done");
        }
      }
    }
  
    public static State state;
    public enum State { LOAD_APPS, RUNNING, EXITING  };
  
    public static InitRunner initRunner;
    public class InitRunner implements Runnable
    {
      private Context context;
      public boolean running = false;
  
      public InitRunner(Context context) {
        this.context = context;
      }
  
      public void stop() {
        running = false;
      }
  
      public void run() {
        MyLog.d("Init begin");
        running = true;
  
        Looper.myLooper().prepare();
  
        state = NetworkLog.State.LOAD_APPS;
        ApplicationsTracker.getInstalledApps(context, handler);
  
        if(running == false) {
          return;
        }
  
        history.loadEntriesFromFile(context, settings.getHistorySize());
  
        if(startServiceAtStart && !isServiceRunning(context, NetworkLogService.class.getName())) {
          handler.post(new Runnable() {
            public void run() {
              startService();
            }
          });
        }
  
        state = NetworkLog.State.RUNNING;
        MyLog.d("Init done");
      }
    }
  
    public void loadSettings() {
      if(settings == null) {
        settings = new Settings(this);
      }
  
      SysUtils.applySamsungFix(this);
  
      filterTextInclude = settings.getFilterTextInclude();
      FilterUtils.buildList(filterTextInclude, filterTextIncludeList);
      filterUidInclude = settings.getFilterUidInclude();
      filterNameInclude = settings.getFilterNameInclude();
      filterAddressInclude = settings.getFilterAddressInclude();
      filterPortInclude = settings.getFilterPortInclude();
      filterInterfaceInclude = settings.getFilterInterfaceInclude();
      filterProtocolInclude = settings.getFilterProtocolInclude();
  
      filterTextExclude = settings.getFilterTextExclude();
      FilterUtils.buildList(filterTextExclude, filterTextExcludeList);
      filterUidExclude = settings.getFilterUidExclude();
      filterNameExclude = settings.getFilterNameExclude();
      filterAddressExclude = settings.getFilterAddressExclude();
      filterPortExclude = settings.getFilterPortExclude();
      filterInterfaceExclude = settings.getFilterInterfaceExclude();
      filterProtocolExclude = settings.getFilterProtocolExclude();
  
      startServiceAtStart = settings.getStartServiceAtStart();
      stopServiceAtExit = settings.getStopServiceAtExit();
  
      resolveHosts = settings.getResolveHosts();
      resolvePorts = settings.getResolvePorts();
      resolveCopies = settings.getResolveCopies();
  
      startServiceAtStart = settings.getStartServiceAtStart();
      stopServiceAtExit = settings.getStopServiceAtExit();
  
      NetworkLogService.throughputBps = settings.getThroughputBps();
      NetworkLogService.toastEnabled = settings.getToastNotifications();
      NetworkLogService.toastDuration = settings.getToastNotificationsDuration();
      NetworkLogService.toastPosition = settings.getToastNotificationsPosition();
      NetworkLogService.toastYOffset = settings.getToastNotificationsYOffset();
      NetworkLogService.toastOpacity = settings.getToastNotificationsOpacity();
      NetworkLogService.toastShowAddress = settings.getToastNotificationsShowAddress();
  
      NetworkLogService.blockedApps = new SelectBlockedApps().loadBlockedApps(this);
      NetworkLogService.toastBlockedApps = new SelectToastApps().loadBlockedApps(this);
    }
  
    private static class MyFragmentPagerAdapter extends FragmentPagerAdapter implements TitleProvider {
      Context context;
  
      public MyFragmentPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        this.context = context;
      }
  
      @Override
        public String getTitle(int index) {
          switch(index) {
            case PAGE_LOG:
              return context.getResources().getString(R.string.tab_log);
            case PAGE_APP:
              return context.getResources().getString(R.string.tab_apps);
          }
          return "Unnamed";
        }
  
      @Override
        public Fragment getItem(int index) {
          Fragment fragment = null;
  
          switch(index) {
            case PAGE_LOG:
              fragment = logFragment;
              break;
            case PAGE_APP:
              fragment = appFragment;
              break;
          }
  
          return fragment;
        }
  
      @Override
        public int getCount() {
          return PAGES;
        }
    }
  
    /** Called when the activity is first created. */
    @Override
      public void onCreate(Bundle savedInstanceState)
      {
        super.onCreate(savedInstanceState);
        MyLog.d("NetworkLog started");
  
        context = this;
        instance = this;
  
        loadSettings();
        getLocalIpAddresses();
  
        data = (RetainInstanceData) getLastCustomNonConfigurationInstance();
  
        if(data != null) {
          MyLog.d("Restored run");
          ApplicationsTracker.restoreData(data);
          resolver = data.networkLogResolver;
  
          // restore history loading progress dialog
          history.dialog_showing = data.historyDialogShowing;
          history.dialog_max = data.historyDialogMax;
          history.dialog_progress = data.historyDialogProgress;
  
          if(history.dialog_showing) {
            history.createProgressDialog(this);
          }
  
          if(data.feedbackDialogMessage != null) {
            feedbackDialog = new FeedbackDialog(this);
            feedbackDialog.setMessage(data.feedbackDialogMessage);
            feedbackDialog.setAttachLogcat(data.feedbackDialogAttachLogcat);
            feedbackDialog.setCursorPosition(data.feedbackDialogCursorPosition);
            feedbackDialog.show();
          }
  
          if(data.clearLogDialogShowing) {
            clearLog.showClearLogDialog(this);
          }
  
          clearLog.progress = data.clearLogProgress;
          clearLog.progress_max = data.clearLogProgressMax;
  
          if(data.clearLogProgressDialogShowing) {
            clearLog.showProgressDialog(this);
          }
  
          if(data.exportDialogShowing) {
            exportDialog = new ExportDialog(this);
            exportDialog.setStartDate(data.exportDialogStartDate);
            exportDialog.setEndDate(data.exportDialogEndDate);
            exportDialog.setFile(data.exportDialogFile);
            exportDialog.show();
            exportDialog.datePickerMode = data.exportDialogDatePickerMode;
            exportDialog.restoreDatePickerListener();
          }
  
          if(data.exportDialogProgressDialogShowing) {
            exportDialog.progress = data.exportDialogProgress;
            exportDialog.progress_max = data.exportDialogProgressMax;
            exportDialog.showProgressDialog(this);
          }
        } else {
          MyLog.d("Fresh run");
          resolver = new NetworkResolver();
  
          logFragment = (LogFragment) Fragment.instantiate(this, LogFragment.class.getName());
          appFragment = (AppFragment) Fragment.instantiate(this, AppFragment.class.getName());
        }
  
        logFragment.setParent(this);
        appFragment.setParent(this);
  
        handler = new Handler();
  
        setContentView(R.layout.main);
  
        ActionBar actionBar = getSupportActionBar();
        actionBar.setCustomView(R.layout.actionbar_top);
        actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM);
  
        if(history == null) {
          history = new HistoryLoader();
        }
  
        if(clearLog == null) {
          clearLog = new ClearLog();
        }
  
        statusText = (TextView) findViewById(R.id.statusText);
  
  