OPP: Check file size before send to prevent crash

Use case :
1. Send large file to dut (Above 4 GB)
Failure:
Crash in com.android.bluetooth.
Process: com.android.bluetooth
java.lang.IllegalArgumentException: Length must be
   between 0 and 0xFFFFFFFF
at javax.obex.HeaderSet.setHeader(HeaderSet.java:333)
at com.android.bluetooth.opp.BluetoothOppObexClientSession$ClientThread
   .sendFile(BluetoothOppObexClientSession.java:411)
at com.android.bluetooth.opp.BluetoothOppObexClientSession$ClientThread
    .doSend(BluetoothOppObexClientSession.java:337)

Root cause :
Largest length in OBEX message header is unsigned 4 bytes, so actual
file length (4 GB) cannot be written into Obex header which leads
to exception in OBEX code.

Fix :
Add length check before push file and skip sendfile if length is above
4GB to prevent crash.

Change-Id: I9066fb7456d85fdc197fe21fed26fb2bb89ff09e
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
index 1d605c0..56b27d8 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppLauncherActivity.java
@@ -53,6 +53,7 @@
 import android.provider.Settings;
 import android.util.Log;
 import android.util.Patterns;
+import android.widget.Toast;
 
 /**
  * This class is designed to act as the entry point of handling the share intent
@@ -109,11 +110,7 @@
                     // session to DB.
                     Thread t = new Thread(new Runnable() {
                         public void run() {
-                            BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
-                                .saveSendingFileInfo(type,stream.toString(), false);
-                            //Done getting file info..Launch device picker and finish this activity
-                            launchDevicePicker();
-                            finish();
+                            sendFileInfo(type, stream.toString(), false);
                         }
                     });
                     t.start();
@@ -125,12 +122,7 @@
                     if (fileUri != null) {
                         Thread t = new Thread(new Runnable() {
                             public void run() {
-                                BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
-                                    .saveSendingFileInfo(type,fileUri.toString(), false);
-                                //Done getting file info..Launch device picker
-                                //and finish this activity
-                                launchDevicePicker();
-                                finish();
+                                sendFileInfo(type, fileUri.toString(), false);
                             }
                         });
                         t.start();
@@ -153,12 +145,17 @@
                                 + mimeType);
                     Thread t = new Thread(new Runnable() {
                         public void run() {
-                            BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
-                                .saveSendingFileInfo(mimeType,uris, false);
-                            //Done getting file info..Launch device picker
-                            //and finish this activity
-                            launchDevicePicker();
-                            finish();
+                            try {
+                                BluetoothOppManager.getInstance(BluetoothOppLauncherActivity.this)
+                                    .saveSendingFileInfo(mimeType, uris, false);
+                                //Done getting file info..Launch device picker
+                                //and finish this activity
+                                launchDevicePicker();
+                                finish();
+                            } catch (IllegalArgumentException exception) {
+                                showToast(exception.getMessage());
+                                finish();
+                            }
                         }
                     });
                     t.start();
@@ -377,4 +374,26 @@
         }
         return text;
     }
+
+    private void sendFileInfo(String mimeType, String uriString, boolean isHandover) {
+        BluetoothOppManager manager = BluetoothOppManager.getInstance(getApplicationContext());
+        try {
+            manager.saveSendingFileInfo(mimeType, uriString, isHandover);
+            launchDevicePicker();
+            finish();
+        } catch (IllegalArgumentException exception) {
+            showToast(exception.getMessage());
+            finish();
+        }
+    }
+
+    private void showToast(final String msg) {
+        BluetoothOppLauncherActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
 }
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
index dd8efe0..bdc61c9 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppManager.java
@@ -246,7 +246,8 @@
         if (V) Log.v(TAG, "Application data stored to SharedPreference! ");
     }
 
-    public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover) {
+    public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover)
+            throws IllegalArgumentException {
         synchronized (BluetoothOppManager.this) {
             mMultipleFlag = false;
             mMimeTypeOfSendingFile = mimeType;
@@ -259,7 +260,8 @@
         }
     }
 
-    public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover) {
+    public void saveSendingFileInfo(String mimeType, ArrayList<Uri> uris, boolean isHandover)
+            throws IllegalArgumentException {
         synchronized (BluetoothOppManager.this) {
             mMultipleFlag = true;
             mMimeTypeOfSendingFiles = mimeType;
diff --git a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
index b9d2b9f..2495f9b 100644
--- a/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
+++ b/android/app/src/com/android/bluetooth/opp/BluetoothOppSendFileInfo.java
@@ -212,6 +212,10 @@
         if (length == 0) {
             Log.e(TAG, "Could not determine size of file");
             return SEND_FILE_INFO_ERROR;
+        } else if (length > 0xffffffffL) {
+            String msg = "Files bigger than 4GB can't be transferred";
+            Log.e(TAG, msg);
+            throw new IllegalArgumentException(msg);
         }
 
         return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0);