// Path: android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/Programmer.java
// public class Programmer {
//     private static final String TAG = "Programmer";
//     private SimpleLogger logger;
// 
//     private FirmwareImage image;
//     private BootloaderConnection conn;
// 
//     private Context context;
//     private Handler handler = new Handler();
// 
//     public Programmer(Context context) {
//         this.context = context;
//     }
// 
//     public void program() {
//         logger = SimpleLogger.getInstance(context);
//         InputStream in = context.getResources().openRawResource(R.raw.walt);
//         image = new FirmwareImage();
//         try {
//             image.parseHex(in);
//         } catch (ParseException e) {
//             Log.e(TAG, "Parsing input file: ", e);
//         }
// 
//         conn = BootloaderConnection.getInstance(context);
//         // TODO: automatically reboot into the bootloader
//         logger.log("\nRemember to press the button on the Teensy first\n");
//         conn.setConnectionStateListener(new WaltConnection.ConnectionStateListener() {
//             @Override
//             public void onConnect() {
//                 handler.post(programRunnable);
//             }
// 
//             @Override
//             public void onDisconnect() {}
//         });
//         if (!conn.isConnected()) {
//             conn.connect();
//         }
//     }
// 
//     private Runnable programRunnable = new Runnable() {
//         @Override
//         public void run() {
//             logger.log("Programming...");
// 
//             // The logic for this is ported from
//             // https://github.com/PaulStoffregen/teensy_loader_cli
//             byte[] buf = new byte[DeviceConstants.BLOCK_SIZE + 64];
//             for (int addr = 0; addr < DeviceConstants.FIRMWARE_SIZE;
//                  addr += DeviceConstants.BLOCK_SIZE) {
//                 if (!image.shouldWrite(addr, DeviceConstants.BLOCK_SIZE) && addr != 0)
//                     continue; // don't need to flash this block
// 
//                 buf[0] = (byte) (addr & 255);
//                 buf[1] = (byte) ((addr >>> 8) & 255);
//                 buf[2] = (byte) ((addr >>> 16) & 255);
//                 Arrays.fill(buf, 3, 64, (byte) 0);
//                 image.getData(buf, 64, addr, DeviceConstants.BLOCK_SIZE);
// 
//                 conn.write(buf, (addr == 0) ? 3000 : 250);
//             }
// 
//             logger.log("Programming complete. Rebooting.");
// 
//             // reboot the device
//             buf[0] = (byte) 0xFF;
//             buf[1] = (byte) 0xFF;
//             buf[2] = (byte) 0xFF;
//             Arrays.fill(buf, 3, DeviceConstants.BLOCK_SIZE + 64, (byte) 0);
//             conn.write(buf, 250);
//         }
//     };
// }
// 
// Path: android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java
// static boolean getBooleanPreference(Context context, @StringRes int keyId, boolean defaultValue) {
//     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
//     return preferences.getBoolean(context.getString(keyId), defaultValue);
// }


import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.Loader;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import org.chromium.latency.walt.programmer.Programmer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.Locale;
import static org.chromium.latency.walt.Utils.getBooleanPreference;
            logger.log("Error syncing clocks: " + e.getMessage());
        }
    }

    public void onClickCheckDrift(View view) {
        waltDevice.checkDrift();
    }

    public void onClickProgram(View view) {
        if (waltDevice.isConnected()) {
            // show dialog telling user to first press white button
            final AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("Press white button")
                .setMessage("Please press the white button on the WALT device.")
                .setCancelable(false)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {}
                }).show();

            waltDevice.setConnectionStateListener(new WaltConnection.ConnectionStateListener() {
                @Override
                public void onConnect() {}

                @Override
                public void onDisconnect() {
                    dialog.cancel();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
// Path: android/WALT/app/src/main/java/org/chromium/latency/walt/programmer/Programmer.java
// public class Programmer {
//     private static final String TAG = "Programmer";
//     private SimpleLogger logger;
// 
//     private FirmwareImage image;
//     private BootloaderConnection conn;
// 
//     private Context context;
//     private Handler handler = new Handler();
// 
//     public Programmer(Context context) {
//         this.context = context;
//     }
// 
//     public void program() {
//         logger = SimpleLogger.getInstance(context);
//         InputStream in = context.getResources().openRawResource(R.raw.walt);
//         image = new FirmwareImage();
//         try {
//             image.parseHex(in);
//         } catch (ParseException e) {
//             Log.e(TAG, "Parsing input file: ", e);
//         }
// 
//         conn = BootloaderConnection.getInstance(context);
//         // TODO: automatically reboot into the bootloader
//         logger.log("\nRemember to press the button on the Teensy first\n");
//         conn.setConnectionStateListener(new WaltConnection.ConnectionStateListener() {
//             @Override
//             public void onConnect() {
//                 handler.post(programRunnable);
//             }
// 
//             @Override
//             public void onDisconnect() {}
//         });
//         if (!conn.isConnected()) {
//             conn.connect();
//         }
//     }
// 
//     private Runnable programRunnable = new Runnable() {
//         @Override
//         public void run() {
//             logger.log("Programming...");
// 
//             // The logic for this is ported from
//             // https://github.com/PaulStoffregen/teensy_loader_cli
//             byte[] buf = new byte[DeviceConstants.BLOCK_SIZE + 64];
//             for (int addr = 0; addr < DeviceConstants.FIRMWARE_SIZE;
//                  addr += DeviceConstants.BLOCK_SIZE) {
//                 if (!image.shouldWrite(addr, DeviceConstants.BLOCK_SIZE) && addr != 0)
//                     continue; // don't need to flash this block
// 
//                 buf[0] = (byte) (addr & 255);
//                 buf[1] = (byte) ((addr >>> 8) & 255);
//                 buf[2] = (byte) ((addr >>> 16) & 255);
//                 Arrays.fill(buf, 3, 64, (byte) 0);
//                 image.getData(buf, 64, addr, DeviceConstants.BLOCK_SIZE);
// 
//                 conn.write(buf, (addr == 0) ? 3000 : 250);
//             }
// 
//             logger.log("Programming complete. Rebooting.");
// 
//             // reboot the device
//             buf[0] = (byte) 0xFF;
//             buf[1] = (byte) 0xFF;
//             buf[2] = (byte) 0xFF;
//             Arrays.fill(buf, 3, DeviceConstants.BLOCK_SIZE + 64, (byte) 0);
//             conn.write(buf, 250);
//         }
//     };
// }
// 
// Path: android/WALT/app/src/main/java/org/chromium/latency/walt/Utils.java
// static boolean getBooleanPreference(Context context, @StringRes int keyId, boolean defaultValue) {
//     SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
//     return preferences.getBoolean(context.getString(keyId), defaultValue);
// }


// Path: android/WALT/app/src/main/java/org/chromium/latency/walt/MainActivity.java
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.StrictMode;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.Loader;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import org.chromium.latency.walt.programmer.Programmer;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Date;
import java.util.Locale;
import static org.chromium.latency.walt.Utils.getBooleanPreference;

            logger.log("Error syncing clocks: " + e.getMessage());
        }
    }

    public void onClickCheckDrift(View view) {
        waltDevice.checkDrift();
    }

    public void onClickProgram(View view) {
        if (waltDevice.isConnected()) {
            // show dialog telling user to first press white button
            final AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("Press white button")
                .setMessage("Please press the white button on the WALT device.")
                .setCancelable(false)
                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {}
                }).show();

            waltDevice.setConnectionStateListener(new WaltConnection.ConnectionStateListener() {
                @Override
                public void onConnect() {}

                @Override
                public void onDisconnect() {
                    dialog.cancel();
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            new Programmer(MainActivity.this).program();