Commit a8a4e4d1 authored by Jeffrey I. Schiller's avatar Jeffrey I. Schiller

De-Bounce the “Connect with Code” Button

De-Bounce the “Connect with Code” Button in the MIT AI2 Companion

The Companion's design is to setup communications with the user's
browser and get to work. Once this process starts, enough things are in
motion that it is best to quit the Companion and start a fresh copy if a
different code is needed.

If the same code is entered more then once, we just ignore the second
attempt. This often happens when someone scans a QR Code and then
presses the "Connect" Button because they do not know that they don't
have to do that. Effectively we are "de-bouncing"

Change-Id: I06b20c5d9cdb07999a380d9f877edd111e0357c5
parent f2c21102
...@@ -175,7 +175,7 @@ public final class Notifier extends AndroidNonvisibleComponent implements Compon ...@@ -175,7 +175,7 @@ public final class Notifier extends AndroidNonvisibleComponent implements Compon
// This method is declared static, with an explicit activity input, so that other // This method is declared static, with an explicit activity input, so that other
// components can use it // components can use it
public static void oneButtonAlert(Activity activity,String message, String title, String buttonText) { public static void oneButtonAlert(Activity activity,String message, String title, String buttonText, final Runnable callBack) {
Log.i(LOG_TAG, "One button alert " + message); Log.i(LOG_TAG, "One button alert " + message);
AlertDialog alertDialog = new AlertDialog.Builder(activity).create(); AlertDialog alertDialog = new AlertDialog.Builder(activity).create();
alertDialog.setTitle(title); alertDialog.setTitle(title);
...@@ -185,10 +185,20 @@ public final class Notifier extends AndroidNonvisibleComponent implements Compon ...@@ -185,10 +185,20 @@ public final class Notifier extends AndroidNonvisibleComponent implements Compon
alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
buttonText, new DialogInterface.OnClickListener() { buttonText, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
if (callBack != null) {
callBack.run();
}
}}); }});
alertDialog.show(); alertDialog.show();
} }
// A version of oneButtonAlert that doesn't accept a callback. We provide this
// for backwards compatibility in case extensions out there are using this (older)
// version which didn't accept a callback
public static void oneButtonAlert(Activity activity,String message, String title, String buttonText) {
oneButtonAlert(activity, message, title, buttonText, null);
}
// converts a string that includes HTML tags to a spannable string that can // converts a string that includes HTML tags to a spannable string that can
// be included in an alert // be included in an alert
private static SpannableString stringToHTML(String message) { private static SpannableString stringToHTML(String message) {
......
...@@ -75,6 +75,8 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component ...@@ -75,6 +75,8 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component
private final Form form; private final Form form;
private static PhoneStatus mainInstance = null; private static PhoneStatus mainInstance = null;
private static boolean useWebRTC = false; private static boolean useWebRTC = false;
private String firstSeed = null;
private String firstHmacSeed = null;
public PhoneStatus(ComponentContainer container) { public PhoneStatus(ComponentContainer container) {
super(container.$form()); super(container.$form());
...@@ -116,6 +118,48 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component ...@@ -116,6 +118,48 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component
"process if we are using WebRTC. This is a bit of a kludge...") "process if we are using WebRTC. This is a bit of a kludge...")
public String setHmacSeedReturnCode(String seed, String rendezvousServer) { public String setHmacSeedReturnCode(String seed, String rendezvousServer) {
/* If we get an empty seed, just ignore it. */
if (seed.equals("")) {
return "";
}
/*
* Check to see if we are being re-entered.
*
* The Companion's design is to setup communications with
* the user's browser and get to work. Once this process starts,
* enough things are in motion that it is best to quit the
* Companion and start a fresh copy if a different code is needed.
*
* If the same code is entered more then once, we just ignore the
* second attempt. This often happens when someone scans a QR Code
* and then presses the "Connect" Button because they do not know
* that they don't have to do that. Effectively we are "de-bouncing"
* the button.
*
*/
if (firstSeed != null) { // Hmm. We've been here before!
if (!firstSeed.equals(seed)) {
// Attempting to use a different seed (code)
// Provide a warning dialog box
Notifier.oneButtonAlert(Form.getActiveForm(),
"You cannot use two codes with one start up of the Companion. You should restart the " +
"Companion and try again.",
"Warning", "OK", new Runnable() {
@Override public void run() {
// We are going to die here, so the user has to start a new copy. This isn't ideal. A more
// correct solution would be to gracefully shutdown the connection process and restart it with
// the new seed.
Form.getActiveForm().finish();
System.exit(0); // Truly ugly...
}
});
}
return firstHmacSeed;
}
firstSeed = seed;
/* Setup communications via WebRTC */ /* Setup communications via WebRTC */
if (useWebRTC) { if (useWebRTC) {
WebRTCNativeMgr webRTCNativeMgr = new WebRTCNativeMgr(rendezvousServer); WebRTCNativeMgr webRTCNativeMgr = new WebRTCNativeMgr(rendezvousServer);
...@@ -140,7 +184,8 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component ...@@ -140,7 +184,8 @@ public class PhoneStatus extends AndroidNonvisibleComponent implements Component
} }
Log.d(LOG_TAG, "Seed = " + seed); Log.d(LOG_TAG, "Seed = " + seed);
Log.d(LOG_TAG, "Code = " + sb.toString()); Log.d(LOG_TAG, "Code = " + sb.toString());
return sb.toString(); firstHmacSeed = sb.toString();
return firstHmacSeed;
} }
@SimpleFunction(description = "Returns true if we are running in the emulator or USB Connection") @SimpleFunction(description = "Returns true if we are running in the emulator or USB Connection")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment