From 2e22f5ed9976e8eeb8adbb3755f07e294a479e04 Mon Sep 17 00:00:00 2001 From: Daniel Pollithy Date: Thu, 18 Jan 2018 19:51:39 +0100 Subject: [PATCH 01/29] fix #25 --- .../com/flashwifi/wifip2p/MainActivity.java | 9 ++ .../flashwifi/wifip2p/RoamingActivity.java | 91 +++++++----- .../com/flashwifi/wifip2p/SearchFragment.java | 6 + .../flashwifi/wifip2p/billing/Accountant.java | 48 ++++++- .../com/flashwifi/wifip2p/billing/Bill.java | 23 +-- .../wifip2p/billing/BillingClient.java | 11 +- .../wifip2p/billing/BillingServer.java | 25 +++- .../broadcast/WiFiDirectBroadcastService.java | 7 +- .../wifip2p/protocol/BillingOpenChannel.java | 9 +- app/src/main/res/layout/activity_roaming.xml | 132 +++++++++++++++--- app/src/main/res/layout/itemlistview.xml | 12 +- app/src/main/res/values/strings.xml | 2 + 12 files changed, 294 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java b/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java index 96ffd6d..421e98a 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java +++ b/app/src/main/java/com/flashwifi/wifip2p/MainActivity.java @@ -19,8 +19,10 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; +import android.view.View; import android.widget.CompoundButton; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.Switch; import android.widget.Toast; @@ -50,6 +52,13 @@ public class MainActivity extends AppCompatActivity updateUIReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { + try { + // hide progress bar + ProgressBar progressConnection = (ProgressBar) findViewById(R.id.progressConnection); + progressConnection.setVisibility(View.VISIBLE); + } catch (Exception e) { + e.printStackTrace(); + } if (intent.getAction().equals("com.flashwifi.wifip2p.start_roaming")) { startRoamingView(intent.getStringExtra("peer_mac_address"), intent.getStringExtra("ssid"), diff --git a/app/src/main/java/com/flashwifi/wifip2p/RoamingActivity.java b/app/src/main/java/com/flashwifi/wifip2p/RoamingActivity.java index dec0f2c..2f2c86e 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/RoamingActivity.java +++ b/app/src/main/java/com/flashwifi/wifip2p/RoamingActivity.java @@ -1,5 +1,6 @@ package com.flashwifi.wifip2p; +import android.annotation.SuppressLint; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -26,6 +27,7 @@ import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -37,6 +39,8 @@ import com.flashwifi.wifip2p.broadcast.WiFiDirectBroadcastService; import com.flashwifi.wifip2p.datastore.PeerStore; import com.flashwifi.wifip2p.protocol.NegotiationFinalization; +import org.w3c.dom.Text; + public class RoamingActivity extends AppCompatActivity { private static final String TAG = "RoamingActivity"; @@ -59,6 +63,7 @@ public class RoamingActivity extends AppCompatActivity { private Button stopButton; private boolean endRoamingFlag = false; + private boolean initiatedEnd; @Override protected void onStart() { @@ -106,6 +111,11 @@ public class RoamingActivity extends AppCompatActivity { flashEstablished.setChecked(true); } else if (message.equals("Billing")) { updateBillingCard(); + } else if (message.equals("Channel closed")) { + exitRoaming(); + if (mService.isInRoleHotspot()) { + showRetransferCard(); + } } } @@ -118,25 +128,44 @@ public class RoamingActivity extends AppCompatActivity { } + private void showRetransferCard() { + CardView cardView = (CardView) findViewById(R.id.card_view_tangle_attachment); + cardView.setVisibility(View.VISIBLE); + } + + @SuppressLint("DefaultLocale") private void updateBillingCard() { CardView summaryView = (CardView) findViewById(R.id.card_view_overview); if (summaryView.getVisibility() != View.VISIBLE) { summaryView.setVisibility(View.VISIBLE); } - String minutes = Integer.toString(Accountant.getInstance().getTotalDurance()); - String megabytes_max = Integer.toString(Accountant.getInstance().getBookedMegabytes()); - String megabytes_used = Integer.toString(Accountant.getInstance().getTotalMegabytes()); - String iotas_transferred = Integer.toString(Accountant.getInstance().getTotalIotaPrice()); + int minutes = Accountant.getInstance().getTotalDurance() / 60; + int minutes_max = Accountant.getInstance().getBookedMinutes(); + int megabytes_max = Accountant.getInstance().getBookedMegabytes(); + int megabytes_used = Accountant.getInstance().getTotalMegabytes(); + int iotas_transferred = Accountant.getInstance().getTotalIotaPrice(); + int iotas_max = Accountant.getInstance().getTotalIotaDeposit(); TextView summaryMinutes = (TextView) findViewById(R.id.summaryMinutes); - summaryMinutes.setText(String.format("%s minutes active", minutes)); + summaryMinutes.setText(String.format("%d/%d minutes active", minutes, minutes_max)); TextView summaryMegabytes = (TextView) findViewById(R.id.summaryMegabytes); - summaryMegabytes.setText(String.format("%s/%s Megabytes roamed", megabytes_used, megabytes_max)); - + summaryMegabytes.setText(String.format("%d/%d Megabytes roamed", megabytes_used, megabytes_max)); TextView summaryIota = (TextView) findViewById(R.id.summaryIota); - summaryMegabytes.setText(String.format("%s Iota transferred", iotas_transferred)); + summaryIota.setText(String.format("%d/%d Iota transferred", iotas_transferred, iotas_max)); + + ProgressBar progressMinutes = (ProgressBar) findViewById(R.id.progressbarDurance); + progressMinutes.setMax(minutes_max); + progressMinutes.setProgress(minutes); + + ProgressBar progressMegabytes = (ProgressBar) findViewById(R.id.progressbarMegabytes); + progressMegabytes.setMax(megabytes_max); + progressMegabytes.setProgress(megabytes_used); + + ProgressBar progressIota = (ProgressBar) findViewById(R.id.progressbarIota); + progressIota.setProgress(iotas_transferred); + progressIota.setMax(iotas_max); } @@ -227,30 +256,7 @@ public class RoamingActivity extends AppCompatActivity { private void initUI() { - //final EditText input = (EditText) findViewById(R.id.chat_input); - //Button button = (Button) findViewById(R.id.btn_send); - /*button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View view) { - addMessageRight(name, input.getText().toString()); - // send the message to the peer - //mService.sendMessageToSocketServer(groupOwnerAddress, input.getText().toString()); - } - });*/ - - /*FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); - fab.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(final View view) { - toggleHotspot(); - } - }); - - listView = (ListView) findViewById(R.id.peer_list); - arrayList = new ArrayList<>(); - - listAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, arrayList); - listView.setAdapter(listAdapter);*/ + updateBillingCard(); } /** Defines callbacks for service binding, passed to bindService() */ @@ -298,6 +304,17 @@ public class RoamingActivity extends AppCompatActivity { } private void endRoaming() { + if (!initiatedEnd) { + initiatedEnd = true; + Accountant.getInstance().setCloseAfterwards(true); + // the next bill will send the close request + // meanwhile show a loading icon + ProgressBar stopProgressBar = (ProgressBar) findViewById(R.id.stopProgressBar); + stopProgressBar.setVisibility(View.VISIBLE); + } + } + + private void exitRoaming() { endRoamingFlag = true; cancelNotification(); if (mService.isInRoleHotspot()){ @@ -306,6 +323,16 @@ public class RoamingActivity extends AppCompatActivity { mService.disconnectAP(); } mService.setRoaming(false); + // hide the spinner and the stop button + ProgressBar stopProgressBar = (ProgressBar) findViewById(R.id.stopProgressBar); + stopProgressBar.setVisibility(View.GONE); + Button stopButton = (Button) findViewById(R.id.stopRoamingButton); + stopButton.setVisibility(View.GONE); + + TextView stopText = (TextView) findViewById(R.id.stopText); + stopText.setVisibility(View.VISIBLE); + + Toast.makeText(getApplicationContext(), "Press BACK now", Toast.LENGTH_LONG).show(); } diff --git a/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java b/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java index af6ee0e..cfdba69 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java +++ b/app/src/main/java/com/flashwifi/wifip2p/SearchFragment.java @@ -21,6 +21,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ListView; +import android.widget.ProgressBar; import android.widget.Toast; import android.widget.ToggleButton; @@ -223,6 +224,11 @@ public class SearchFragment extends Fragment { public void onItemClick(AdapterView adapterView, View view, int i, long l) { if (!busy) { busy = true; + + // show progress bar + ProgressBar progressConnection = (ProgressBar) getActivity().findViewById(R.id.progressConnection); + progressConnection.setVisibility(View.VISIBLE); + PeerInformation peer = PeerStore.getInstance().getPeerArrayList().get(i); peer.setSelected(true); diff --git a/app/src/main/java/com/flashwifi/wifip2p/billing/Accountant.java b/app/src/main/java/com/flashwifi/wifip2p/billing/Accountant.java index 619f1ac..213aff4 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/billing/Accountant.java +++ b/app/src/main/java/com/flashwifi/wifip2p/billing/Accountant.java @@ -12,7 +12,11 @@ public class Accountant { private int totalIotaPrice; private int totalDurance; private int bookedMegabytes; + private int bookedMinutes; + private int totalIotaDeposit; private int timeoutMinutes; + private boolean closeAfterwards; + private long startTime; private FlashChannelHelper flashChannelHelper; @@ -25,19 +29,39 @@ public class Accountant { private Accountant() { } - public void start(int bookedMegabytes, int timeoutMinutes){ + public void start(int bookedMegabytes, int timeoutMinutes, int bookedMinutes, int totalIotaDeposit){ if (closed) { bills = new ArrayList(); this.bookedMegabytes = bookedMegabytes; this.timeoutMinutes = timeoutMinutes; + this.totalIotaDeposit = totalIotaDeposit; totalMegabytes = 0; totalIotaPrice = 0; totalDurance = 0; flashChannelHelper = new FlashChannelHelper(); + closeAfterwards = false; + startTime = System.currentTimeMillis() / 1000L; + this.bookedMinutes = bookedMinutes; closed = false; } } + private long getLastTime() { + if (bills.isEmpty()) { + return startTime; + } else { + return bills.get(bills.size()-1).getTime(); + } + } + + public boolean isCloseAfterwards() { + return closeAfterwards; + } + + public void setCloseAfterwards(boolean closeAfterwards) { + this.closeAfterwards = closeAfterwards; + } + public int getNextBillNumber() { return bills.size() + 1; } @@ -56,20 +80,22 @@ public class Accountant { totalMegabytes += b.getMegabytesUsed(); totalIotaPrice += b.getPriceInIota(); - totalDurance += b.getDuranceInMinutes(); + totalDurance += b.getDuranceInSeconds(); // ToDo: apply transfer to flash channel return true; } - public Bill createBill(int megaByte, int priceInIota, int duranceMinutes){ + public Bill createBill(int megaByte, int priceInIota){ if (!closed) { - Bill b = new Bill(getNextBillNumber(), totalDurance, duranceMinutes, megaByte, priceInIota); + long now = System.currentTimeMillis() / 1000L; + long duranceInSeconds = now - getLastTime(); + Bill b = new Bill(getNextBillNumber(), now, duranceInSeconds, megaByte, priceInIota); totalMegabytes += megaByte; totalIotaPrice += priceInIota; - totalDurance += duranceMinutes; + totalDurance += duranceInSeconds; // 1) modify flash channel applyTransferToFlashChannel(priceInIota); @@ -114,4 +140,16 @@ public class Accountant { public int getBookedMegabytes() { return bookedMegabytes; } + + public int getTimeoutMinutes() { + return timeoutMinutes; + } + + public int getBookedMinutes() { + return bookedMinutes; + } + + public int getTotalIotaDeposit() { + return totalIotaDeposit; + } } diff --git a/app/src/main/java/com/flashwifi/wifip2p/billing/Bill.java b/app/src/main/java/com/flashwifi/wifip2p/billing/Bill.java index b3bb0cb..4f3dd4b 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/billing/Bill.java +++ b/app/src/main/java/com/flashwifi/wifip2p/billing/Bill.java @@ -3,17 +3,17 @@ package com.flashwifi.wifip2p.billing; public class Bill { private int index; - private int minuteStart; - private int duranceInMinutes = 1; private int megabytesUsed; private int priceInIota; + private long duranceInSeconds; + private long time; private boolean acceptedByPeer; - public Bill(int index, int minuteStart, int duranceInMinutes, int megabytesUsed, int priceInIota) { + public Bill(int index, long time, long duranceInSeconds, int megabytesUsed, int priceInIota) { this.index = index; - this.minuteStart = minuteStart; - this.duranceInMinutes = duranceInMinutes; + this.time = time; + this.duranceInSeconds = duranceInSeconds; this.megabytesUsed = megabytesUsed; this.priceInIota = priceInIota; } @@ -30,12 +30,13 @@ public class Bill { return index; } - public int getMinuteStart() { - return minuteStart; - } public int getDuranceInMinutes() { - return duranceInMinutes; + return (int) duranceInSeconds/60; + } + + public int getDuranceInSeconds() { + return (int) duranceInSeconds; } public int getMegabytesUsed() { @@ -45,4 +46,8 @@ public class Bill { public int getPriceInIota() { return priceInIota; } + + public long getTime() { + return time; + } } diff --git a/app/src/main/java/com/flashwifi/wifip2p/billing/BillingClient.java b/app/src/main/java/com/flashwifi/wifip2p/billing/BillingClient.java index 7555740..85a3e39 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/billing/BillingClient.java +++ b/app/src/main/java/com/flashwifi/wifip2p/billing/BillingClient.java @@ -1,5 +1,6 @@ package com.flashwifi.wifip2p.billing; +import android.accounts.Account; import android.content.Context; import android.content.Intent; import android.util.Log; @@ -74,15 +75,17 @@ public class BillingClient { String hotspotStateLine = socketWrapper.getLineThrowing(); if (hotspotStateLine.contains("INITIAL") || hotspotStateLine.contains("NOT_PAIRED")) { // ask the hotspot to open the flash channel + // ToDo: get real digests String[] digests = new String[]{"1234", "2345", "3456"}; - billingOpenChannel = new BillingOpenChannel(100, 100, "clientAddress", 8, digests, 20 * 60 * 1000); + // ToDo: replace magic numbers + billingOpenChannel = new BillingOpenChannel(100, 100, "clientAddress", 8, digests, 20 * 60 * 1000, 60); String billingOpenChannelString = gson.toJson(billingOpenChannel); socketWrapper.sendLine(billingOpenChannelString); // receive the hotspot details for the flash channel String billingOpenChannelAnswerString = socketWrapper.getLineThrowing(); billingOpenChannelAnswer = gson.fromJson(billingOpenChannelAnswerString, BillingOpenChannelAnswer.class); // now create the flash channel on our side - Accountant.getInstance().start(billingOpenChannel.getTotalMegabytes(), billingOpenChannel.getTimeoutMinutesClient()); + Accountant.getInstance().start(billingOpenChannel.getTotalMegabytes(), billingOpenChannel.getTimeoutMinutesClient(), billingOpenChannel.getTotalMinutes(), billingOpenChannelAnswer.getClientDepositIota()); sendUpdateUIBroadcastWithMessage("Channel established"); state = State.ROAMING; } else { @@ -106,7 +109,7 @@ public class BillingClient { // ToDo: flash object -> diff() // ToDo: sign flash transaction sendUpdateUIBroadcastWithMessage("Billing"); - latestBillAnswer = new BillMessageAnswer("id", true, "", false); + latestBillAnswer = new BillMessageAnswer("id", true, "", Accountant.getInstance().isCloseAfterwards()); latestBillAnswerString = gson.toJson(latestBillAnswer); socketWrapper.sendLine(latestBillAnswerString); @@ -128,6 +131,8 @@ public class BillingClient { String billingCloseChannelAnswerString = gson.toJson(billingCloseChannelAnswer); socketWrapper.sendLine(billingCloseChannelAnswerString); + sendUpdateUIBroadcastWithMessage("Channel closed"); + state = State.CLOSED; } diff --git a/app/src/main/java/com/flashwifi/wifip2p/billing/BillingServer.java b/app/src/main/java/com/flashwifi/wifip2p/billing/BillingServer.java index 1b21a17..cef1ee2 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/billing/BillingServer.java +++ b/app/src/main/java/com/flashwifi/wifip2p/billing/BillingServer.java @@ -2,6 +2,8 @@ package com.flashwifi.wifip2p.billing; import android.content.Context; import android.content.Intent; +import android.net.wifi.WifiManager; +import android.text.format.Formatter; import android.util.Log; import com.flashwifi.wifip2p.negotiation.SocketWrapper; @@ -20,6 +22,8 @@ import java.net.Socket; import java.net.SocketException; import java.net.UnknownHostException; +import static android.content.Context.WIFI_SERVICE; + /** * 1) This class keeps the socket connection alive. * 2) It tracks the state of the communication. @@ -48,9 +52,9 @@ public class BillingServer { context.sendBroadcast(local); } - public BillingServer(int bookedMegabytes, int timeoutMinutes, Context context){ + public BillingServer(int bookedMegabytes, int timeoutMinutes, int maxMinutes, int iotaDepositClient, Context context){ this.context = context; - Accountant.getInstance().start(bookedMegabytes,timeoutMinutes); + Accountant.getInstance().start(bookedMegabytes, timeoutMinutes, maxMinutes, iotaDepositClient); gson = new GsonBuilder().create(); } @@ -59,6 +63,10 @@ public class BillingServer { createDeadlineGuard(); // 1) create a socket + Log.d(TAG, "start: Billing server has been started"); + + // ToDo: receive end of roaming broadcast + while (state != State.CLOSED) { try { // create server socket @@ -117,10 +125,9 @@ public class BillingServer { Log.d(TAG, "start: Good morning!"); // create new bill // ToDo: integrate real network data - // ToDo: calculate time correctly - b = Accountant.getInstance().createBill(0,0,1); + b = Accountant.getInstance().createBill(3,9); // ToDo: integrate real flash channel - latestBill = new BillMessage(b, "", false); + latestBill = new BillMessage(b, "", Accountant.getInstance().isCloseAfterwards()); latestBillString = gson.toJson(latestBill); socketWrapper.sendLine(latestBillString); @@ -136,11 +143,14 @@ public class BillingServer { if (latestBill.isCloseAfterwards() || latestBillAnswer.isCloseAfterwards()) { state = State.CLOSE; } + + sendUpdateUIBroadcastWithMessage("Billing"); } } if (state == State.CLOSE) { + Log.d(TAG, "start: state is CLOSE now"); // ToDo: handle the final deposit of the flash channel // ToDo: sign the transaction BillingCloseChannel billingCloseChannel = new BillingCloseChannel(0,0,0,0,"", "", ""); @@ -150,6 +160,9 @@ public class BillingServer { String billingCloseChannelAnswerString = socketWrapper.getLineThrowing(); BillingCloseChannelAnswer billingCloseChannelAnswer = gson.fromJson(billingCloseChannelAnswerString, BillingCloseChannelAnswer.class); // ToDo: validate the signature + + // change the ui + sendUpdateUIBroadcastWithMessage("Channel closed"); state = State.CLOSED; } @@ -162,7 +175,7 @@ public class BillingServer { state = State.FULLY_ATTACHED; } } catch (IOException e) { - + e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } diff --git a/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java b/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java index abdf621..217cb66 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java +++ b/app/src/main/java/com/flashwifi/wifip2p/broadcast/WiFiDirectBroadcastService.java @@ -101,8 +101,9 @@ public class WiFiDirectBroadcastService extends Service { Runnable task = new Runnable() { @Override public void run() { + Log.d(TAG, "run: instantiate billing server"); // ToDo: remove magic numbers - BillingServer billingServer = new BillingServer(100, 20, getApplicationContext()); + BillingServer billingServer = new BillingServer(100, 20, 60, 100, getApplicationContext()); try { billingServer.start(); @@ -115,8 +116,10 @@ public class WiFiDirectBroadcastService extends Service { }; Log.d(TAG, "startBillingServer"); Thread thread = new Thread(task); + //asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); + //AsyncTask.execute(thread); threads.add(thread); - AsyncTask.execute(thread); + thread.start(); } } diff --git a/app/src/main/java/com/flashwifi/wifip2p/protocol/BillingOpenChannel.java b/app/src/main/java/com/flashwifi/wifip2p/protocol/BillingOpenChannel.java index 9ce6cd1..067b795 100644 --- a/app/src/main/java/com/flashwifi/wifip2p/protocol/BillingOpenChannel.java +++ b/app/src/main/java/com/flashwifi/wifip2p/protocol/BillingOpenChannel.java @@ -3,6 +3,7 @@ package com.flashwifi.wifip2p.protocol; public class BillingOpenChannel { private int totalMegabytes; + private int totalMinutes; private int iotaPerMegabyte; private int timeoutMinutesClient; private String clientRefundAddress; @@ -10,8 +11,10 @@ public class BillingOpenChannel { private String[] clientDigests; public BillingOpenChannel(int totalMegabytes, int iotaPerMegabyte, String clientRefundAddress, - int treeDepth, String[] clientDigests, int timeoutMinutesClient) { + int treeDepth, String[] clientDigests, int timeoutMinutesClient, + int totalMinutes) { this.totalMegabytes = totalMegabytes; + this.totalMinutes = totalMinutes; this.iotaPerMegabyte = iotaPerMegabyte; this.clientRefundAddress = clientRefundAddress; this.treeDepth = treeDepth; @@ -42,4 +45,8 @@ public class BillingOpenChannel { public String[] getClientDigests() { return clientDigests; } + + public int getTotalMinutes() { + return totalMinutes; + } } diff --git a/app/src/main/res/layout/activity_roaming.xml b/app/src/main/res/layout/activity_roaming.xml index e7c87f8..4ca539a 100644 --- a/app/src/main/res/layout/activity_roaming.xml +++ b/app/src/main/res/layout/activity_roaming.xml @@ -60,21 +60,88 @@ android:clickable="false" android:text="Flash channel" /> -