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

Skip to content
Snippets Groups Projects
Commit 2a15994a authored by str4d's avatar str4d
Browse files

Load real stats into NetDb ViewPager

getRouterContext() returns null in onActivityCreated(), there is a race
condition to fix somewhere, use refresh action to load.
parent e9549531
No related branches found
No related tags found
No related merge requests found
package net.i2p.android.router.fragment;
import java.util.List;
import net.i2p.android.router.R;
import net.i2p.android.router.loader.NetDbStatsLoader;
import net.i2p.android.router.util.Util;
import net.i2p.util.ObjectCounter;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
public class NetDbSummaryPagerFragment extends Fragment {
public class NetDbSummaryPagerFragment extends I2PFragmentBase implements
LoaderManager.LoaderCallbacks<List<ObjectCounter<String>>> {
NetDbPagerAdapter mNetDbPagerAdapter;
ViewPager mViewPager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.parentfragment_viewpager, container, false);
......@@ -39,19 +56,66 @@ public class NetDbSummaryPagerFragment extends Fragment {
});
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
LoaderManager lm = getLoaderManager();
// If the Router is running, or there is an existing Loader
if (getRouterContext() != null || lm.getLoader(0) != null) {
lm.initLoader(0, null, this);
} else {
// Router is not running or is not bound yet.
Util.i("Router not running or not bound to NetDbSummaryPagerFragment");
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.fragment_netdb_list_actions, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_refresh:
Util.i("Refresh called, restarting Loader");
mNetDbPagerAdapter.setData(null);
mViewPager.invalidate();
getLoaderManager().restartLoader(0, null, this);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public class NetDbPagerAdapter extends FragmentStatePagerAdapter {
private List<ObjectCounter<String>> mData;
public NetDbPagerAdapter(FragmentManager fm) {
super(fm);
}
public void setData(List<ObjectCounter<String>> data) {
mData = data;
notifyDataSetChanged();
}
@Override
public Fragment getItem(int i) {
return NetDbSummaryTableFragment.newInstance(i);
if (mData == null)
return null;
return NetDbSummaryTableFragment.newInstance(i, mData.get(i));
}
@Override
public int getCount() {
return 3;
if (mData == null)
return 0;
else
return 3;
}
@Override
......@@ -66,4 +130,19 @@ public class NetDbSummaryPagerFragment extends Fragment {
}
}
}
// LoaderManager.LoaderCallbacks<List<ObjectCounter<String>>>
public Loader<List<ObjectCounter<String>>> onCreateLoader(int id, Bundle args) {
return new NetDbStatsLoader(getActivity(), getRouterContext());
}
public void onLoadFinished(Loader<List<ObjectCounter<String>>> loader,
List<ObjectCounter<String>> data) {
mNetDbPagerAdapter.setData(data);
}
public void onLoaderReset(Loader<List<ObjectCounter<String>>> loader) {
mNetDbPagerAdapter.setData(null);
}
}
package net.i2p.android.router.fragment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.i2p.android.router.R;
import net.i2p.util.ObjectCounter;
import net.i2p.util.VersionComparator;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
......@@ -12,14 +18,18 @@ import android.widget.TextView;
public class NetDbSummaryTableFragment extends Fragment {
private static final String CATEGORY = "category";
private static final String COUNTS = "counts";
private int mCategory;
private ObjectCounter<String> mCounts;
private TableLayout mTable;
public static NetDbSummaryTableFragment newInstance(int category) {
public static NetDbSummaryTableFragment newInstance(int category,
ObjectCounter<String> counts) {
NetDbSummaryTableFragment f = new NetDbSummaryTableFragment();
Bundle args = new Bundle();
args.putInt(CATEGORY, category);
args.putSerializable(COUNTS, counts);
f.setArguments(args);
return f;
}
......@@ -29,13 +39,30 @@ public class NetDbSummaryTableFragment extends Fragment {
View v = inflater.inflate(R.layout.fragment_table, container, false);
mCategory = getArguments().getInt(CATEGORY);
mCounts = (ObjectCounter<String>) getArguments().getSerializable(COUNTS);
mTable = (TableLayout) v.findViewById(R.id.table);
createTableTitle();
addTableRow("foo", "123");
addTableRow("bar", "45");
if (mCategory == 2)
addTableRow("bing", "67");
List<String> objects = new ArrayList<String>(mCounts.objects());
if (!objects.isEmpty()) {
createTableTitle();
switch (mCategory) {
case 1:
case 2:
Collections.sort(objects);
break;
default:
Collections.sort(objects,
Collections.reverseOrder(new VersionComparator()));
break;
}
for (String object : objects) {
int num = mCounts.count(object);
addTableRow(object, ""+num);
}
}
return v;
}
......
package net.i2p.android.router.loader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import net.i2p.data.Hash;
import net.i2p.data.RouterAddress;
import net.i2p.data.RouterInfo;
import net.i2p.router.RouterContext;
import net.i2p.util.ObjectCounter;
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class NetDbStatsLoader extends AsyncTaskLoader<List<ObjectCounter<String>>> {
private RouterContext mRContext;
private List<ObjectCounter<String>> mData;
public NetDbStatsLoader(Context context, RouterContext rContext) {
super(context);
mRContext = rContext;
}
private static class RouterInfoComparator implements Comparator<RouterInfo> {
public int compare(RouterInfo l, RouterInfo r) {
return l.getHash().toBase64().compareTo(r.getHash().toBase64());
}
}
@Override
public List<ObjectCounter<String>> loadInBackground() {
List<ObjectCounter<String>> ret = new ArrayList<ObjectCounter<String>>();
ObjectCounter<String> versions = new ObjectCounter<String>();
ObjectCounter<String> countries = new ObjectCounter<String>();
ObjectCounter<String> transports = new ObjectCounter<String>();
if (mRContext.netDb().isInitialized()) {
Hash us = mRContext.routerHash();
Set<RouterInfo> routers = new TreeSet<RouterInfo>(new RouterInfoComparator());
routers.addAll(mRContext.netDb().getRouters());
for (RouterInfo ri : routers) {
Hash key = ri.getHash();
if (!key.equals(us)) {
String routerVersion = ri.getOption("router.version");
if (routerVersion != null)
versions.increment(routerVersion);
String country = mRContext.commSystem().getCountry(key);
if(country != null)
countries.increment(country);
transports.increment(classifyTransports(ri));
}
}
}
ret.add(versions);
ret.add(countries);
ret.add(transports);
return ret;
}
private static final int SSU = 1;
private static final int SSUI = 2;
private static final int NTCP = 4;
private static final int IPV6 = 8;
private static final String[] TNAMES = { "Hidden or starting up", "SSU", "SSU with introducers", "",
"NTCP", "NTCP and SSU", "NTCP and SSU with introducers", "",
"", "IPv6 SSU", "IPv6 Only SSU, introducers", "IPv6 SSU, introducers",
"IPv6 NTCP", "IPv6 NTCP, SSU", "IPv6 Only NTCP, SSU, introducers", "IPv6 NTCP, SSU, introducers" };
/**
* what transport types
*/
private static String classifyTransports(RouterInfo info) {
int rv = 0;
for (RouterAddress addr : info.getAddresses()) {
String style = addr.getTransportStyle();
if (style.equals("NTCP")) {
rv |= NTCP;
} else if (style.equals("SSU")) {
if (addr.getOption("iport0") != null)
rv |= SSUI;
else
rv |= SSU;
}
String host = addr.getHost();
if (host != null && host.contains(":"))
rv |= IPV6;
}
return TNAMES[rv];
}
@Override
public void deliverResult(List<ObjectCounter<String>> data) {
if (isReset()) {
// The Loader has been reset; ignore the result and invalidate the data.
if (data != null) {
releaseResources(data);
return;
}
}
// Hold a reference to the old data so it doesn't get garbage collected.
// We must protect it until the new data has been delivered.
List<ObjectCounter<String>> oldData = mData;
mData = data;
if (isStarted()) {
// If the Loader is in a started state, have the superclass deliver the
// results to the client.
super.deliverResult(data);
}
// Invalidate the old data as we don't need it any more.
if (oldData != null && oldData != data) {
releaseResources(oldData);
}
}
@Override
protected void onStartLoading() {
if (mData != null) {
// Deliver any previously loaded data immediately.
deliverResult(mData);
}
if (takeContentChanged() || mData == null) {
// When the observer detects a change, it should call onContentChanged()
// on the Loader, which will cause the next call to takeContentChanged()
// to return true. If this is ever the case (or if the current data is
// null), we force a new load.
forceLoad();
}
}
@Override
protected void onStopLoading() {
// The Loader is in a stopped state, so we should attempt to cancel the
// current load (if there is one).
cancelLoad();
// Note that we leave the observer as is. Loaders in a stopped state
// should still monitor the data source for changes so that the Loader
// will know to force a new load if it is ever started again.
}
@Override
protected void onReset() {
// Ensure the loader has been stopped.
onStopLoading();
// At this point we can release the resources associated with 'mData'.
if (mData != null) {
releaseResources(mData);
mData = null;
}
}
@Override
public void onCanceled(List<ObjectCounter<String>> data) {
// Attempt to cancel the current asynchronous load.
super.onCanceled(data);
// The load has been canceled, so we should release the resources
// associated with 'data'.
releaseResources(data);
}
private void releaseResources(List<ObjectCounter<String>> data) {
// For a simple List, there is nothing to do. For something like a Cursor, we
// would close it in this method. All resources associated with the Loader
// should be released here.
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment