Expanded NetDB detail pages to match /netdb
This commit is contained in:
@ -14,11 +14,53 @@
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dbentry_hash"
|
||||
android:id="@+id/ls_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/ls_nickname"
|
||||
android:text="Destination" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dbentry_hash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/ls_type"
|
||||
android:text="LeaseSet hash" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_ls_expiry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/dbentry_hash"
|
||||
android:text="Expires in:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ls_expiry"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@+id/label_ls_expiry"
|
||||
android:layout_alignBottom="@+id/label_ls_expiry"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="X min" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_leases"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/label_ls_expiry"
|
||||
android:text="Leases:" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ls_leases"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/label_leases"
|
||||
android:orientation="vertical" >
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -10,4 +10,53 @@
|
||||
android:layout_alignParentLeft="true"
|
||||
android:text="Router hash" />
|
||||
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/label_ri_published"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/dbentry_hash"
|
||||
android:text="Published:" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ri_published"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@+id/label_ri_published"
|
||||
android:layout_alignBottom="@+id/label_ri_published"
|
||||
android:layout_alignParentRight="true"
|
||||
android:text="X ago" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_ri_addresses"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/label_ri_published"
|
||||
android:text="Address(es):" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/ri_addresses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/label_ri_addresses"
|
||||
android:orientation="vertical" >
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label_ri_stats"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/ri_addresses"
|
||||
android:text="Stats:" />
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/ri_stats"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_below="@+id/label_ri_stats" />
|
||||
|
||||
</RelativeLayout>
|
@ -4,7 +4,7 @@ import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.fragment.NetDbDetailFragment;
|
||||
import net.i2p.android.router.fragment.NetDbListFragment;
|
||||
import net.i2p.android.router.fragment.NetDbSummaryPagerFragment;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import net.i2p.data.Hash;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
@ -110,22 +110,22 @@ public class NetDbActivity extends I2PActivityBase implements
|
||||
|
||||
// NetDbListFragment.OnEntrySelectedListener
|
||||
|
||||
public void onEntrySelected(NetDbEntry entry) {
|
||||
public void onEntrySelected(boolean isRouterInfo, Hash entryHash) {
|
||||
if (mTwoPane) {
|
||||
// In two-pane mode, show the detail view in this activity by
|
||||
// adding or replacing the detail fragment using a
|
||||
// fragment transaction.
|
||||
NetDbDetailFragment detailFrag = NetDbDetailFragment.newInstance(
|
||||
entry.isRouterInfo(), entry.getHash());
|
||||
isRouterInfo, entryHash);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.detail_fragment, detailFrag).commit();
|
||||
} else {
|
||||
// In single-pane mode, simply start the detail activity
|
||||
// for the selected item ID.
|
||||
Intent detailIntent = new Intent(this, NetDbDetailActivity.class);
|
||||
detailIntent.putExtra(NetDbDetailFragment.IS_RI, entry.isRouterInfo());
|
||||
detailIntent.putExtra(NetDbDetailFragment.IS_RI, isRouterInfo);
|
||||
detailIntent.putExtra(NetDbDetailFragment.ENTRY_HASH,
|
||||
entry.getHash().toBase64());
|
||||
entryHash.toBase64());
|
||||
startActivity(detailIntent);
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,16 @@ package net.i2p.android.router.activity;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.fragment.NetDbDetailFragment;
|
||||
import net.i2p.android.router.fragment.NetDbListFragment;
|
||||
import net.i2p.android.router.service.RouterService;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.Hash;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
public class NetDbDetailActivity extends I2PActivityBase {
|
||||
public class NetDbDetailActivity extends I2PActivityBase implements
|
||||
NetDbListFragment.OnEntrySelectedListener {
|
||||
NetDbDetailFragment mDetailFrag;
|
||||
|
||||
@Override
|
||||
@ -34,4 +37,15 @@ public class NetDbDetailActivity extends I2PActivityBase {
|
||||
protected void onRouterBind(RouterService svc) {
|
||||
mDetailFrag.onRouterBind();
|
||||
}
|
||||
|
||||
// NetDbListFragment.OnEntrySelectedListener
|
||||
|
||||
public void onEntrySelected(boolean isRouterInfo, Hash entryHash) {
|
||||
// Start the detail activity for the selected item ID.
|
||||
Intent detailIntent = new Intent(this, NetDbDetailActivity.class);
|
||||
detailIntent.putExtra(NetDbDetailFragment.IS_RI, isRouterInfo);
|
||||
detailIntent.putExtra(NetDbDetailFragment.ENTRY_HASH,
|
||||
entryHash.toBase64());
|
||||
startActivity(detailIntent);
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,36 @@
|
||||
package net.i2p.android.router.fragment;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.fragment.NetDbListFragment.OnEntrySelectedListener;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import net.i2p.android.router.util.Util;
|
||||
import net.i2p.data.DataFormatException;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.Lease;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.RouterAddress;
|
||||
import net.i2p.data.RouterInfo;
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TableRow;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class NetDbDetailFragment extends I2PFragmentBase {
|
||||
public static final String IS_RI = "is_routerinfo";
|
||||
public static final String ENTRY_HASH = "entry_hash";
|
||||
|
||||
OnEntrySelectedListener mEntrySelectedCallback;
|
||||
private NetDbEntry mEntry;
|
||||
|
||||
public static NetDbDetailFragment newInstance(boolean isRI, Hash hash) {
|
||||
@ -28,6 +42,21 @@ public class NetDbDetailFragment extends I2PFragmentBase {
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
|
||||
// This makes sure that the container activity has implemented
|
||||
// the callback interface. If not, it throws an exception
|
||||
try {
|
||||
mEntrySelectedCallback = (OnEntrySelectedListener) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implement OnEntrySelectedListener");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
@ -60,21 +89,162 @@ public class NetDbDetailFragment extends I2PFragmentBase {
|
||||
try {
|
||||
hash.fromBase64(getArguments().getString(ENTRY_HASH));
|
||||
if (getArguments().getBoolean(IS_RI)) {
|
||||
// Load RouterInfo
|
||||
RouterInfo ri = getNetDb().lookupRouterInfoLocally(hash);
|
||||
mEntry = NetDbEntry.fromRouterInfo(getRouterContext(), ri);
|
||||
loadRouterInfo(ri);
|
||||
} else {
|
||||
// Load LeaseSet
|
||||
LeaseSet ls = getNetDb().lookupLeaseSetLocally(hash);
|
||||
mEntry = NetDbEntry.fromLeaseSet(getRouterContext(), ls);
|
||||
|
||||
TextView nickname = (TextView) getView().findViewById(R.id.ls_nickname);
|
||||
nickname.setText(mEntry.getNickname());
|
||||
loadLeaseSet(ls);
|
||||
}
|
||||
|
||||
TextView entryHash = (TextView) getView().findViewById(R.id.dbentry_hash);
|
||||
entryHash.setText(hash.toBase64());
|
||||
} catch (DataFormatException e) {
|
||||
Util.e(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadRouterInfo(RouterInfo ri) {
|
||||
mEntry = NetDbEntry.fromRouterInfo(getRouterContext(), ri);
|
||||
|
||||
if (mEntry.isUs())
|
||||
getActivity().setTitle("Our info");
|
||||
else
|
||||
getActivity().setTitle("Peer info");
|
||||
|
||||
TextView entryHash = (TextView) getView().findViewById(R.id.dbentry_hash);
|
||||
entryHash.setText(mEntry.getHash().toBase64());
|
||||
|
||||
if (mEntry.isUs() && getRouter().isHidden()) {
|
||||
TextView pubLabel = (TextView) getView().findViewById(R.id.label_ri_published);
|
||||
pubLabel.setText("Hidden, Updated:");
|
||||
}
|
||||
|
||||
TextView published = (TextView) getView().findViewById(R.id.ri_published);
|
||||
long age = getRouterContext().clock().now() - ri.getPublished();
|
||||
if (age > 0) {
|
||||
published.setText(DataHelper.formatDuration(age) + " ago");
|
||||
} else {
|
||||
// shouldn't happen
|
||||
published.setText(DataHelper.formatDuration(0-age) + " ago???");
|
||||
}
|
||||
|
||||
LinearLayout addresses = (LinearLayout) getView().findViewById(R.id.ri_addresses);
|
||||
for (RouterAddress addr : ri.getAddresses()) {
|
||||
addAddress(addresses, addr);
|
||||
}
|
||||
|
||||
TableLayout stats = (TableLayout) getView().findViewById(R.id.ri_stats);
|
||||
Map<String, String> p = ri.getOptionsMap();
|
||||
for (Map.Entry<String,String> e : (Set<Map.Entry<String,String>>) p.entrySet()) {
|
||||
String key = e.getKey();
|
||||
String val = e.getValue();
|
||||
addTableRow(stats, DataHelper.stripHTML(key), DataHelper.stripHTML(val));
|
||||
}
|
||||
}
|
||||
|
||||
private void addAddress(LinearLayout addresses, RouterAddress addr) {
|
||||
TableLayout table = new TableLayout(getActivity());
|
||||
|
||||
String style = addr.getTransportStyle();
|
||||
addTableRow(table, "Style", style);
|
||||
|
||||
int cost = addr.getCost();
|
||||
if (!((style.equals("SSU") && cost == 5) || (style.equals("NTCP") && cost == 10)))
|
||||
addTableRow(table, "cost", ""+cost);
|
||||
|
||||
Map<String, String> p = addr.getOptionsMap();
|
||||
for (Map.Entry<String,String> e : (Set<Map.Entry<String,String>>) p.entrySet()) {
|
||||
String key = e.getKey();
|
||||
String val = e.getValue();
|
||||
addTableRow(table, DataHelper.stripHTML(key), DataHelper.stripHTML(val));
|
||||
}
|
||||
|
||||
addresses.addView(table);
|
||||
}
|
||||
|
||||
private void loadLeaseSet(LeaseSet ls) {
|
||||
mEntry = NetDbEntry.fromLeaseSet(getRouterContext(), ls);
|
||||
|
||||
getActivity().setTitle("LeaseSet");
|
||||
|
||||
TextView nickname = (TextView) getView().findViewById(R.id.ls_nickname);
|
||||
nickname.setText(mEntry.getNickname());
|
||||
|
||||
TextView type = (TextView) getView().findViewById(R.id.ls_type);
|
||||
if (mEntry.isLocal()) {
|
||||
if (mEntry.isUnpublished())
|
||||
type.setText("Local Unpublished Destination");
|
||||
else
|
||||
type.setText("Local Destination");
|
||||
}
|
||||
|
||||
TextView entryHash = (TextView) getView().findViewById(R.id.dbentry_hash);
|
||||
entryHash.setText(mEntry.getHash().toBase64());
|
||||
|
||||
TextView expiry = (TextView) getView().findViewById(R.id.ls_expiry);
|
||||
long exp = ls.getLatestLeaseDate() - getRouterContext().clock().now();
|
||||
if (exp > 0) {
|
||||
expiry.setText(DataHelper.formatDuration(exp));
|
||||
} else {
|
||||
TextView expiryLabel = (TextView) getView().findViewById(R.id.label_ls_expiry);
|
||||
expiryLabel.setText("Expired:");
|
||||
expiry.setText(DataHelper.formatDuration(exp) + " ago");
|
||||
}
|
||||
|
||||
LinearLayout leases = (LinearLayout) getView().findViewById(R.id.ls_leases);
|
||||
for (int i = 0; i < ls.getLeaseCount(); i++) {
|
||||
Lease lease = ls.getLease(i);
|
||||
addLease(leases, lease, i);
|
||||
}
|
||||
}
|
||||
|
||||
private void addLease(LinearLayout leases, Lease lease, int i) {
|
||||
TableLayout table = new TableLayout(getActivity());
|
||||
|
||||
addTableRow(table, "Lease", ""+(i+1));
|
||||
|
||||
TableRow gateway = new TableRow(getActivity());
|
||||
gateway.setPadding(10, 0, 0, 0);
|
||||
|
||||
TextView gatewayLabel = new TextView(getActivity());
|
||||
gatewayLabel.setText("Gateway");
|
||||
|
||||
Button gatewayButton = new Button(getActivity());
|
||||
gatewayButton.setText(lease.getGateway().toBase64().substring(0, 4));
|
||||
final Hash gatewayHash = lease.getGateway();
|
||||
gatewayButton.setOnClickListener(new OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
mEntrySelectedCallback.onEntrySelected(
|
||||
true, gatewayHash);
|
||||
}
|
||||
});
|
||||
|
||||
gateway.addView(gatewayLabel);
|
||||
gateway.addView(gatewayButton);
|
||||
|
||||
table.addView(gateway);
|
||||
|
||||
addTableRow(table, "Tunnel", ""+lease.getTunnelId().getTunnelId());
|
||||
|
||||
leases.addView(table);
|
||||
}
|
||||
|
||||
private void addTableRow(TableLayout table, String key, String val) {
|
||||
TableRow row;
|
||||
TextView tl1, tl2;
|
||||
|
||||
row = new TableRow(getActivity());
|
||||
row.setPadding(10, 0, 0, 0);
|
||||
|
||||
tl1 = new TextView(getActivity());
|
||||
tl2 = new TextView(getActivity());
|
||||
|
||||
tl1.setText(key);
|
||||
tl2.setText(val);
|
||||
|
||||
row.addView(tl1);
|
||||
row.addView(tl2);
|
||||
|
||||
table.addView(row);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import net.i2p.android.router.R;
|
||||
import net.i2p.android.router.adapter.NetDbEntryAdapter;
|
||||
import net.i2p.android.router.loader.NetDbEntry;
|
||||
import net.i2p.android.router.loader.NetDbEntryLoader;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -48,7 +49,7 @@ public class NetDbListFragment extends ListFragment
|
||||
|
||||
// Container Activity must implement this interface
|
||||
public interface OnEntrySelectedListener {
|
||||
public void onEntrySelected(NetDbEntry entry);
|
||||
public void onEntrySelected(boolean isRouterInfo, Hash entryHash);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -124,7 +125,9 @@ public class NetDbListFragment extends ListFragment
|
||||
@Override
|
||||
public void onListItemClick(ListView parent, View view, int pos, long id) {
|
||||
super.onListItemClick(parent, view, pos, id);
|
||||
mEntrySelectedCallback.onEntrySelected(mAdapter.getItem(pos));
|
||||
NetDbEntry entry = mAdapter.getItem(pos);
|
||||
mEntrySelectedCallback.onEntrySelected(
|
||||
entry.isRouterInfo(), entry.getHash());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -15,21 +15,31 @@ public class NetDbEntry {
|
||||
private final boolean mIsRI;
|
||||
private final DatabaseEntry mEntry;
|
||||
|
||||
private final boolean mIsUs;
|
||||
private final String mCountry;
|
||||
|
||||
private final String mNick;
|
||||
private final boolean mLocal;
|
||||
private final boolean mUnpublished;
|
||||
|
||||
public static NetDbEntry fromRouterInfo(RouterContext ctx, RouterInfo ri) {
|
||||
Hash us = ctx.routerHash();
|
||||
boolean isUs = ri.getHash().equals(us);
|
||||
String country = ctx.commSystem().getCountry(ri.getIdentity().getHash());
|
||||
return new NetDbEntry(true, ri, country, "");
|
||||
return new NetDbEntry(ri, isUs, country);
|
||||
}
|
||||
|
||||
public static NetDbEntry fromLeaseSet(RouterContext ctx, LeaseSet ls) {
|
||||
String nick;
|
||||
String nick = "";
|
||||
boolean local = false;
|
||||
boolean unpublished = false;
|
||||
Destination dest = ls.getDestination();
|
||||
Hash key = dest.calculateHash();
|
||||
if (ctx.clientManager().isLocal(dest)) {
|
||||
TunnelPoolSettings in = ctx.tunnelManager().getInboundSettings(
|
||||
dest.calculateHash());
|
||||
local = true;
|
||||
if (! ctx.clientManager().shouldPublishLeaseSet(key))
|
||||
unpublished = true;
|
||||
TunnelPoolSettings in = ctx.tunnelManager().getInboundSettings(key);
|
||||
if (in != null && in.getDestinationNickname() != null)
|
||||
nick = in.getDestinationNickname();
|
||||
else
|
||||
@ -41,18 +51,32 @@ public class NetDbEntry {
|
||||
else
|
||||
nick = dest.toBase64().substring(0, 6);
|
||||
}
|
||||
return new NetDbEntry(false, ls, "", nick);
|
||||
return new NetDbEntry(ls, nick, local, unpublished);
|
||||
}
|
||||
|
||||
public NetDbEntry(boolean isRI, DatabaseEntry entry,
|
||||
String country,
|
||||
String nick) {
|
||||
mIsRI = isRI;
|
||||
mEntry = entry;
|
||||
public NetDbEntry(RouterInfo ri,
|
||||
boolean isUs, String country) {
|
||||
mIsRI = true;
|
||||
mEntry = ri;
|
||||
|
||||
mIsUs = isUs;
|
||||
mCountry = country;
|
||||
|
||||
mNick = "";
|
||||
mLocal = mUnpublished = false;
|
||||
}
|
||||
|
||||
public NetDbEntry(LeaseSet ls,
|
||||
String nick, boolean local, boolean unpublished) {
|
||||
mIsRI = false;
|
||||
mEntry = ls;
|
||||
|
||||
mNick = nick;
|
||||
mLocal = local;
|
||||
mUnpublished = unpublished;
|
||||
|
||||
mIsUs = false;
|
||||
mCountry = "";
|
||||
}
|
||||
|
||||
public boolean isRouterInfo() {
|
||||
@ -67,6 +91,10 @@ public class NetDbEntry {
|
||||
|
||||
// RouterInfo-specific methods
|
||||
|
||||
public boolean isUs() {
|
||||
return mIsUs;
|
||||
}
|
||||
|
||||
public int getCountryIcon() {
|
||||
// http://daniel-codes.blogspot.com/2009/12/dynamically-retrieving-resources-in.html
|
||||
try {
|
||||
@ -84,4 +112,12 @@ public class NetDbEntry {
|
||||
public String getNickname() {
|
||||
return mNick;
|
||||
}
|
||||
|
||||
public boolean isLocal() {
|
||||
return mLocal;
|
||||
}
|
||||
|
||||
public boolean isUnpublished() {
|
||||
return mUnpublished;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user