// Path: AndroidApp/src/de/schildbach/wallet/util/LinuxSecureRandom.java
// public class LinuxSecureRandom extends SecureRandomSpi
// {
//     private static final long serialVersionUID = -6575880163829115605L;
//     private static final FileInputStream urandom;
// 
//     private static class LinuxSecureRandomProvider extends Provider
//     {
//         private static final long serialVersionUID = -3366530978335459636L;
// 
//         public LinuxSecureRandomProvider()
//         {
//             super("LinuxSecureRandom", 1.0, "A Linux specific random number provider that uses /dev/urandom");
//             put("SecureRandom.LinuxSecureRandom", LinuxSecureRandom.class.getName());
//         }
//     }
// 
//     static
//     {
//         try
//         {
//             File file = new File("/dev/urandom");
//             if (file.exists())
//             {
//                 // This stream is deliberately leaked.
//                 urandom = new FileInputStream(file);
//                 // Now override the default SecureRandom implementation with this one.
//                 Security.insertProviderAt(new LinuxSecureRandomProvider(), 1);
//             }
//             else
//             {
//                 urandom = null;
//             }
//         }
//         catch (FileNotFoundException e)
//         {
//             // Should never happen.
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private final DataInputStream dis;
// 
//     public LinuxSecureRandom()
//     {
//         // DataInputStream is not thread safe, so each random object has its own.
//         dis = new DataInputStream(urandom);
//     }
// 
//     @Override
//     protected void engineSetSeed(byte[] bytes)
//     {
//         // Ignore.
//     }
// 
//     @Override
//     protected void engineNextBytes(byte[] bytes)
//     {
//         try
//         {
//             dis.readFully(bytes); // This will block until all the bytes can be read.
//         }
//         catch (IOException e)
//         {
//             throw new RuntimeException(e); // Fatal error. Do not attempt to recover from this.
//         }
//     }
// 
//     @Override
//     protected byte[] engineGenerateSeed(int i)
//     {
//         byte[] bits = new byte[i];
//         engineNextBytes(bits);
//         return bits;
//     }
// }


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.FileObserver;
import android.os.Handler;
import android.util.Base64;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import de.schildbach.wallet.util.LinuxSecureRandom;
            // writes to that file, then renames to <target>. There's no CLOSE_WRITE event for <target>.
            super(
                directory.getAbsolutePath(),
                FileObserver.MOVED_TO | FileObserver.CLOSE_WRITE);
            mTargetFilenames = new ArrayList<String>(Arrays.asList(filenames));
            mLatch = new CountDownLatch(mTargetFilenames.size());
        }

        @Override
        public void onEvent(int event, String path) {
            if (path != null) {
                for (int i = 0; i < mTargetFilenames.size(); i++) {
                    if (path.equals(mTargetFilenames.get(i))) {
                        mTargetFilenames.remove(i);
                        mLatch.countDown();
                        if (mTargetFilenames.size() == 0) {
                            stopWatching();
                        }
                        break;
                    }
                }
            }
        }

        public boolean await(long timeoutMilliseconds) throws InterruptedException {
            return mLatch.await(timeoutMilliseconds, TimeUnit.MILLISECONDS);
        }
    }

    public static void initSecureRandom() {
// Path: AndroidApp/src/de/schildbach/wallet/util/LinuxSecureRandom.java
// public class LinuxSecureRandom extends SecureRandomSpi
// {
//     private static final long serialVersionUID = -6575880163829115605L;
//     private static final FileInputStream urandom;
// 
//     private static class LinuxSecureRandomProvider extends Provider
//     {
//         private static final long serialVersionUID = -3366530978335459636L;
// 
//         public LinuxSecureRandomProvider()
//         {
//             super("LinuxSecureRandom", 1.0, "A Linux specific random number provider that uses /dev/urandom");
//             put("SecureRandom.LinuxSecureRandom", LinuxSecureRandom.class.getName());
//         }
//     }
// 
//     static
//     {
//         try
//         {
//             File file = new File("/dev/urandom");
//             if (file.exists())
//             {
//                 // This stream is deliberately leaked.
//                 urandom = new FileInputStream(file);
//                 // Now override the default SecureRandom implementation with this one.
//                 Security.insertProviderAt(new LinuxSecureRandomProvider(), 1);
//             }
//             else
//             {
//                 urandom = null;
//             }
//         }
//         catch (FileNotFoundException e)
//         {
//             // Should never happen.
//             throw new RuntimeException(e);
//         }
//     }
// 
//     private final DataInputStream dis;
// 
//     public LinuxSecureRandom()
//     {
//         // DataInputStream is not thread safe, so each random object has its own.
//         dis = new DataInputStream(urandom);
//     }
// 
//     @Override
//     protected void engineSetSeed(byte[] bytes)
//     {
//         // Ignore.
//     }
// 
//     @Override
//     protected void engineNextBytes(byte[] bytes)
//     {
//         try
//         {
//             dis.readFully(bytes); // This will block until all the bytes can be read.
//         }
//         catch (IOException e)
//         {
//             throw new RuntimeException(e); // Fatal error. Do not attempt to recover from this.
//         }
//     }
// 
//     @Override
//     protected byte[] engineGenerateSeed(int i)
//     {
//         byte[] bits = new byte[i];
//         engineNextBytes(bits);
//         return bits;
//     }
// }


// Path: AndroidApp/src/ca/psiphon/ploggy/Utils.java
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.location.Location;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.FileObserver;
import android.os.Handler;
import android.util.Base64;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import de.schildbach.wallet.util.LinuxSecureRandom;

            // writes to that file, then renames to <target>. There's no CLOSE_WRITE event for <target>.
            super(
                directory.getAbsolutePath(),
                FileObserver.MOVED_TO | FileObserver.CLOSE_WRITE);
            mTargetFilenames = new ArrayList<String>(Arrays.asList(filenames));
            mLatch = new CountDownLatch(mTargetFilenames.size());
        }

        @Override
        public void onEvent(int event, String path) {
            if (path != null) {
                for (int i = 0; i < mTargetFilenames.size(); i++) {
                    if (path.equals(mTargetFilenames.get(i))) {
                        mTargetFilenames.remove(i);
                        mLatch.countDown();
                        if (mTargetFilenames.size() == 0) {
                            stopWatching();
                        }
                        break;
                    }
                }
            }
        }

        public boolean await(long timeoutMilliseconds) throws InterruptedException {
            return mLatch.await(timeoutMilliseconds, TimeUnit.MILLISECONDS);
        }
    }

    public static void initSecureRandom() {
        new LinuxSecureRandom();