Android Open Source - bitfynd-wallet-android Peer List Fragment






From Project

Back to project page bitfynd-wallet-android.

License

The source code is released under:

GNU General Public License

If you think the Android project bitfynd-wallet-android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright 2012-2014 the original author or authors.
 */*from   w  w w. j  ava 2s . co  m*/
 * 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 de.schildbach.wallet.ui;

import java.net.InetAddress;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.RejectedExecutionException;

import javax.annotation.Nonnull;

import org.bitcoinj.core.Peer;
import org.bitcoinj.core.VersionMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.AsyncTaskLoader;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.Loader;
import android.content.ServiceConnection;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.text.format.DateUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import de.schildbach.wallet.service.BlockchainService;
import de.schildbach.wallet.service.BlockchainServiceImpl;
import de.schildbach.wallet.util.WholeStringBuilder;
import de.schildbach.wallet.R;

/**
 * @author Andreas Schildbach
 */
public final class PeerListFragment extends FancyListFragment
{
  private AbstractWalletActivity activity;
  private LoaderManager loaderManager;

  private BlockchainService service;
  private ArrayAdapter<Peer> adapter;

  private final Handler handler = new Handler();

  private static final long REFRESH_MS = DateUtils.SECOND_IN_MILLIS;

  private static final int ID_PEER_LOADER = 0;
  private static final int ID_REVERSE_DNS_LOADER = 1;

  private final Map<InetAddress, String> hostnames = new WeakHashMap<InetAddress, String>();

  private static final Logger log = LoggerFactory.getLogger(PeerListFragment.class);

  @Override
  public void onAttach(final Activity activity)
  {
    super.onAttach(activity);

    this.activity = (AbstractWalletActivity) activity;
    this.loaderManager = getLoaderManager();
  }

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

    activity.bindService(new Intent(activity, BlockchainServiceImpl.class), serviceConnection, Context.BIND_AUTO_CREATE);
  }

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

    adapter = new ArrayAdapter<Peer>(activity, 0)
    {
      private final LayoutInflater inflater = LayoutInflater.from(activity);

      @Override
      public View getView(final int position, View row, final ViewGroup parent)
      {
        if (row == null)
          row = inflater.inflate(R.layout.peer_list_row, null);

        final Peer peer = getItem(position);
        final VersionMessage versionMessage = peer.getPeerVersionMessage();
        final boolean isDownloading = peer.getDownloadData();

        final TextView rowIp = (TextView) row.findViewById(R.id.peer_list_row_ip);
        final InetAddress address = peer.getAddress().getAddr();
        final String hostname = hostnames.get(address);
        rowIp.setText(hostname != null ? hostname : address.getHostAddress());

        final TextView rowHeight = (TextView) row.findViewById(R.id.peer_list_row_height);
        final long bestHeight = peer.getBestHeight();
        rowHeight.setText(bestHeight > 0 ? bestHeight + " blocks" : null);
        rowHeight.setTypeface(isDownloading ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);

        final TextView rowVersion = (TextView) row.findViewById(R.id.peer_list_row_version);
        rowVersion.setText(versionMessage.subVer);
        rowVersion.setTypeface(isDownloading ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);

        final TextView rowProtocol = (TextView) row.findViewById(R.id.peer_list_row_protocol);
        rowProtocol.setText("protocol: " + versionMessage.clientVersion);
        rowProtocol.setTypeface(isDownloading ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);

        final TextView rowPing = (TextView) row.findViewById(R.id.peer_list_row_ping);
        final long pingTime = peer.getPingTime();
        rowPing.setText(pingTime < Long.MAX_VALUE ? getString(R.string.peer_list_row_ping_time, pingTime) : null);
        rowPing.setTypeface(isDownloading ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT);

        return row;
      }

      @Override
      public boolean isEnabled(final int position)
      {
        return false;
      }
    };
    setListAdapter(adapter);
  }

  @Override
  public void onResume()
  {
    super.onResume();

    handler.postDelayed(new Runnable()
    {
      @Override
      public void run()
      {
        adapter.notifyDataSetChanged();

        final Loader<String> loader = loaderManager.getLoader(ID_REVERSE_DNS_LOADER);
        final boolean loaderRunning = loader != null && loader.isStarted();

        if (!loaderRunning)
        {
          for (int i = 0; i < adapter.getCount(); i++)
          {
            final Peer peer = adapter.getItem(i);
            final InetAddress address = peer.getAddress().getAddr();

            if (!hostnames.containsKey(address))
            {
              final Bundle args = new Bundle();
              args.putSerializable("address", address);
              loaderManager.initLoader(ID_REVERSE_DNS_LOADER, args, reverseDnsLoaderCallbacks).forceLoad();

              break;
            }
          }
        }

        handler.postDelayed(this, REFRESH_MS);
      }
    }, REFRESH_MS);
  }

  @Override
  public void onPause()
  {
    handler.removeCallbacksAndMessages(null);

    super.onPause();
  }

  @Override
  public void onDestroy()
  {
    activity.unbindService(serviceConnection);

    loaderManager.destroyLoader(ID_REVERSE_DNS_LOADER);

    super.onDestroy();
  }

  private final ServiceConnection serviceConnection = new ServiceConnection()
  {
    @Override
    public void onServiceConnected(final ComponentName name, final IBinder binder)
    {
      service = ((BlockchainServiceImpl.LocalBinder) binder).getService();

      loaderManager.initLoader(ID_PEER_LOADER, null, peerLoaderCallbacks);
    }

    @Override
    public void onServiceDisconnected(final ComponentName name)
    {
      loaderManager.destroyLoader(ID_PEER_LOADER);

      service = null;
    }
  };

  private static class PeerLoader extends AsyncTaskLoader<List<Peer>>
  {
    private LocalBroadcastManager broadcastManager;
    private BlockchainService service;

    private PeerLoader(final Context context, @Nonnull final BlockchainService service)
    {
      super(context);

      this.broadcastManager = LocalBroadcastManager.getInstance(context.getApplicationContext());
      this.service = service;
    }

    @Override
    protected void onStartLoading()
    {
      super.onStartLoading();

      broadcastManager.registerReceiver(broadcastReceiver, new IntentFilter(BlockchainService.ACTION_PEER_STATE));

      forceLoad();
    }

    @Override
    protected void onStopLoading()
    {
      broadcastManager.unregisterReceiver(broadcastReceiver);

      super.onStopLoading();
    }

    @Override
    public List<Peer> loadInBackground()
    {
      return service.getConnectedPeers();
    }

    private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver()
    {
      @Override
      public void onReceive(final Context context, final Intent intent)
      {
        try
        {
          forceLoad();
        }
        catch (final RejectedExecutionException x)
        {
          log.info("rejected execution: " + PeerLoader.this.toString());
        }
      }
    };
  }

  private final LoaderCallbacks<List<Peer>> peerLoaderCallbacks = new LoaderCallbacks<List<Peer>>()
  {
    @Override
    public Loader<List<Peer>> onCreateLoader(final int id, final Bundle args)
    {
      return new PeerLoader(activity, service);
    }

    @Override
    public void onLoadFinished(final Loader<List<Peer>> loader, final List<Peer> peers)
    {
      adapter.clear();

      if (peers != null)
        for (final Peer peer : peers)
          adapter.add(peer);

      setEmptyText(WholeStringBuilder.bold(getString(R.string.peer_list_fragment_empty)));
    }

    @Override
    public void onLoaderReset(final Loader<List<Peer>> loader)
    {
      adapter.clear();
    }
  };

  private static class ReverseDnsLoader extends AsyncTaskLoader<String>
  {
    public final InetAddress address;

    public ReverseDnsLoader(final Context context, @Nonnull final InetAddress address)
    {
      super(context);

      this.address = address;
    }

    @Override
    public String loadInBackground()
    {
      return address.getCanonicalHostName();
    }
  }

  private final LoaderCallbacks<String> reverseDnsLoaderCallbacks = new LoaderCallbacks<String>()
  {
    @Override
    public Loader<String> onCreateLoader(final int id, final Bundle args)
    {
      final InetAddress address = (InetAddress) args.getSerializable("address");

      return new ReverseDnsLoader(activity, address);
    }

    @Override
    public void onLoadFinished(final Loader<String> loader, final String hostname)
    {
      final InetAddress address = ((ReverseDnsLoader) loader).address;
      hostnames.put(address, hostname);

      loaderManager.destroyLoader(ID_REVERSE_DNS_LOADER);
    }

    @Override
    public void onLoaderReset(final Loader<String> loader)
    {
    }
  };
}




Java Source Code List

de.schildbach.wallet.AddressBookProvider.java
de.schildbach.wallet.Configuration.java
de.schildbach.wallet.Constants.java
de.schildbach.wallet.ExchangeRatesProvider.java
de.schildbach.wallet.FileAttachmentProvider.java
de.schildbach.wallet.WalletApplication.java
de.schildbach.wallet.WalletBalanceWidgetProvider.java
de.schildbach.wallet.camera.CameraManager.java
de.schildbach.wallet.data.PaymentIntent.java
de.schildbach.wallet.integration.android.BitcoinIntegration.java
de.schildbach.wallet.offline.AcceptBluetoothService.java
de.schildbach.wallet.offline.AcceptBluetoothThread.java
de.schildbach.wallet.offline.DirectPaymentTask.java
de.schildbach.wallet.service.AutosyncReceiver.java
de.schildbach.wallet.service.BlockchainServiceImpl.java
de.schildbach.wallet.service.BlockchainService.java
de.schildbach.wallet.service.BlockchainStateLoader.java
de.schildbach.wallet.service.BlockchainState.java
de.schildbach.wallet.service.UpgradeWalletService.java
de.schildbach.wallet.ui.AbstractBindServiceActivity.java
de.schildbach.wallet.ui.AbstractWalletActivity.java
de.schildbach.wallet.ui.AddressAndLabel.java
de.schildbach.wallet.ui.AddressBookActivity.java
de.schildbach.wallet.ui.BlockListFragment.java
de.schildbach.wallet.ui.CurrencyAmountView.java
de.schildbach.wallet.ui.CurrencyCalculatorLink.java
de.schildbach.wallet.ui.CurrencySymbolDrawable.java
de.schildbach.wallet.ui.CurrencyTextView.java
de.schildbach.wallet.ui.DialogBuilder.java
de.schildbach.wallet.ui.EditAddressBookEntryFragment.java
de.schildbach.wallet.ui.EncryptKeysDialogFragment.java
de.schildbach.wallet.ui.ExchangeRateLoader.java
de.schildbach.wallet.ui.ExchangeRatesActivity.java
de.schildbach.wallet.ui.ExchangeRatesFragment.java
de.schildbach.wallet.ui.FancyListFragment.java
de.schildbach.wallet.ui.FileAdapter.java
de.schildbach.wallet.ui.HelpDialogFragment.java
de.schildbach.wallet.ui.ImportDialogButtonEnablerListener.java
de.schildbach.wallet.ui.InputParser.java
de.schildbach.wallet.ui.MaybeMaintenanceFragment.java
de.schildbach.wallet.ui.NetworkMonitorActivity.java
de.schildbach.wallet.ui.PeerListFragment.java
de.schildbach.wallet.ui.ProgressDialogFragment.java
de.schildbach.wallet.ui.ReportIssueDialogBuilder.java
de.schildbach.wallet.ui.RequestCoinsActivity.java
de.schildbach.wallet.ui.RequestCoinsFragment.java
de.schildbach.wallet.ui.RestoreWalletActivity.java
de.schildbach.wallet.ui.ScanActivity.java
de.schildbach.wallet.ui.ScannerView.java
de.schildbach.wallet.ui.SendCoinsQrActivity.java
de.schildbach.wallet.ui.SendingAddressesFragment.java
de.schildbach.wallet.ui.ShowPasswordCheckListener.java
de.schildbach.wallet.ui.TransactionsListAdapter.java
de.schildbach.wallet.ui.TransactionsListFragment.java
de.schildbach.wallet.ui.WalletActionsFragment.java
de.schildbach.wallet.ui.WalletActivity.java
de.schildbach.wallet.ui.WalletAddressFragment.java
de.schildbach.wallet.ui.WalletAddressesAdapter.java
de.schildbach.wallet.ui.WalletAddressesFragment.java
de.schildbach.wallet.ui.WalletBalanceFragment.java
de.schildbach.wallet.ui.WalletBalanceLoader.java
de.schildbach.wallet.ui.WalletDisclaimerFragment.java
de.schildbach.wallet.ui.WalletTransactionsFragment.java
de.schildbach.wallet.ui.preference.AboutFragment.java
de.schildbach.wallet.ui.preference.DiagnosticsFragment.java
de.schildbach.wallet.ui.preference.PreferenceActivity.java
de.schildbach.wallet.ui.preference.SettingsFragment.java
de.schildbach.wallet.ui.send.DecodePrivateKeyTask.java
de.schildbach.wallet.ui.send.DeriveKeyTask.java
de.schildbach.wallet.ui.send.MaintenanceDialogFragment.java
de.schildbach.wallet.ui.send.RequestPaymentRequestTask.java
de.schildbach.wallet.ui.send.RequestWalletBalanceTask.java
de.schildbach.wallet.ui.send.SendCoinsActivity.java
de.schildbach.wallet.ui.send.SendCoinsFragment.java
de.schildbach.wallet.ui.send.SendCoinsOfflineTask.java
de.schildbach.wallet.ui.send.SweepWalletActivity.java
de.schildbach.wallet.ui.send.SweepWalletFragment.java
de.schildbach.wallet.util.Base43.java
de.schildbach.wallet.util.BitmapFragment.java
de.schildbach.wallet.util.Bluetooth.java
de.schildbach.wallet.util.CircularProgressView.java
de.schildbach.wallet.util.CrashReporter.java
de.schildbach.wallet.util.Crypto.java
de.schildbach.wallet.util.Formats.java
de.schildbach.wallet.util.GenericUtils.java
de.schildbach.wallet.util.HttpGetThread.java
de.schildbach.wallet.util.Io.java
de.schildbach.wallet.util.Iso8601Format.java
de.schildbach.wallet.util.LinuxSecureRandom.java
de.schildbach.wallet.util.MonetarySpannable.java
de.schildbach.wallet.util.Nfc.java
de.schildbach.wallet.util.Qr.java
de.schildbach.wallet.util.ThrottlingWalletChangeListener.java
de.schildbach.wallet.util.ViewPagerTabs.java
de.schildbach.wallet.util.WalletUtils.java
de.schildbach.wallet.util.WholeStringBuilder.java