Enable file upload, WLAN alert and estore URI

 - Implement file upload feature.
     1. Allow selecting a file to upload from device
     2. Port DRM check's for carrier.

 - Bring in wap2estore changes to browser from 3.7.1
      This feature contains two points:
        1. When user input text starting with "estore:" in url bar,
           will go to estore app when installed or go to download
           client webpage when uninstalled.
        2. When user click one hyperlink whose url starts with "estore"
           in webpage, will be the same behavior as above case.

 - Alert user when WLAN is not available and request using mobile data

Change-Id: I2b93d82c19ea13f36889c3171ef695187d77a12b
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index e3a7308..1d535a4 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -129,14 +129,15 @@
         "android.speech.extras.SEND_APPLICATION_ID_EXTRA";
     private static final String INCOGNITO_URI = "browser:incognito";
 
-
-    private static final String PROP_NETSWITCH = "persist.env.browser.netswitch";
-    private static final String INTENT_WIFI_SELECTION_DATA_CONNECTION =
-            "android.net.wifi.cmcc.WIFI_SELECTION_DATA_CONNECTION";
     private static final String OFFLINE_PAGE =
-            "content://com.android.browser.mynavigation/websites";
-    private static final String INTENT_PICK_NETWORK =
-            "android.net.wifi.cmcc.PICK_WIFI_NETWORK_AND_GPRS";
+        "content://com.android.browser.mynavigation/websites";
+
+    private static final String ACTION_WIFI_SELECTION_DATA_CONNECTION =
+             "android.net.wifi.cmcc.WIFI_SELECTION_DATA_CONNECTION";
+    // Remind switch to data connection if wifi is unavailable
+    private static final int NETWORK_SWITCH_TYPE_OK = 1;
+    private static final String WIFI_BROWSER_INTERACTION_REMIND_TYPE =
+             "wifi_browser_interaction_remind";
 
     public final static String EXTRA_SHARE_SCREENSHOT = "share_screenshot";
     public final static String EXTRA_SHARE_FAVICON = "share_favicon";
@@ -875,55 +876,30 @@
 
     private void handleNetworkNotify(WebView view) {
         ConnectivityManager conMgr = (ConnectivityManager) this.getContext().getSystemService(
-                Context.CONNECTIVITY_SERVICE);
-        WifiManager wifiMgr = (WifiManager) this.getContext()
-                .getSystemService(Context.WIFI_SERVICE);
-        int networkSwitchTypeOK = this.getContext().getResources()
-                .getInteger(R.integer.netswitch_type_remind);
+            Context.CONNECTIVITY_SERVICE);
+        NetworkInfo networkInfo = conMgr.getActiveNetworkInfo();
+        if (networkInfo == null
+            || (networkInfo != null && (networkInfo.getType() !=
+                ConnectivityManager.TYPE_WIFI))) {
+            int isReminder = Settings.System.getInt(
+                mActivity.getContentResolver(),
+                WIFI_BROWSER_INTERACTION_REMIND_TYPE,
+                NETWORK_SWITCH_TYPE_OK);
 
-        if (wifiMgr.isWifiEnabled()) {
-            NetworkInfo mNetworkInfo = conMgr.getActiveNetworkInfo();
-            if (mNetworkInfo == null
-                    || (mNetworkInfo != null && (mNetworkInfo.getType() !=
-                    ConnectivityManager.TYPE_WIFI))) {
-                List<ScanResult> list = wifiMgr.getScanResults();
-                if (list != null && list.size() == 0) {
-                    int isReminder = Settings.System.getInt(
-                            mActivity.getContentResolver(),
-                            this.getContext().getResources()
-                                    .getString(R.string.network_switch_remind_type),
-                            networkSwitchTypeOK);
-                    if (isReminder == networkSwitchTypeOK) {
-                        Intent intent = new Intent(
-                                INTENT_WIFI_SELECTION_DATA_CONNECTION);
-                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                        this.getContext().startActivity(intent);
-                    }
-                } else {
-                    if ((Boolean)ReflectHelper.invokeMethod(
-                             "android.app.ActivityManagerNative", "isSystemReady", null, null)) {
-                        try {
-                            Intent intent = new Intent(INTENT_PICK_NETWORK);
-                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                            this.getContext().startActivity(intent);
-                        } catch (Exception e) {
-                            String err_msg = this.getContext().getString(
-                                    R.string.acivity_not_found, INTENT_PICK_NETWORK);
-                            Toast.makeText(this.getContext(), err_msg, Toast.LENGTH_LONG).show();
-                        }
-                    } else {
-                        Log.e(LOGTAG, "System is not ready!");
-                    }
+        if (isReminder == NETWORK_SWITCH_TYPE_OK) {
+            mNetworkShouldNotify = false;
+                Intent intent = new Intent(
+                    ACTION_WIFI_SELECTION_DATA_CONNECTION);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                this.getContext().startActivity(intent);
+            } else {
+                if (!mNetworkHandler.isNetworkUp()) {
+                    view.setNetworkAvailable(false);
                 }
-                mNetworkShouldNotify = false;
-            }
-        } else {
-            if (!mNetworkHandler.isNetworkUp()) {
-                view.setNetworkAvailable(false);
-                Log.v(LOGTAG, "handleNetworkNotify() Wlan is not enabled.");
             }
         }
     }
+
     // WebViewController
 
     @Override
@@ -938,28 +914,11 @@
 
         // reset sync timer to avoid sync starts during loading a page
         CookieSyncManager.getInstance().resetSync();
-        Object[] params  = {new String(PROP_NETSWITCH),
-                            new Boolean(false)};
-        Class[] type = new Class[] {String.class, boolean.class};
-        Boolean result = (Boolean) ReflectHelper.invokeMethod(
-                        "android.os.SystemProperties", "getBoolean",
-                        type, params);
-        if (result) {
-            if (!mNetworkHandler.isNetworkUp()) {
-                Log.d(LOGTAG, "onPageStarted() network unavailable");
-                if (mNetworkShouldNotify) {
-                    handleNetworkNotify(view);
-                } else {
-                    view.setNetworkAvailable(false);
-                }
-                mNetworkShouldNotify = false;
-            } else {
-                Log.d(LOGTAG, "onPageStarted() network available");
-                if (mNetworkShouldNotify) {
-                    handleNetworkNotify(view);
-                }
-                mNetworkShouldNotify = false;
-            }
+        WifiManager wifiMgr = (WifiManager) this.getContext()
+            .getSystemService(Context.WIFI_SERVICE);
+        String browserRes = mActivity.getResources().getString(R.string.config_carrier_resource);
+        if ("cmcc".equals(browserRes) && mNetworkShouldNotify && wifiMgr.isWifiEnabled()) {
+            handleNetworkNotify(view);
         } else {
             if (!mNetworkHandler.isNetworkUp()) {
                 view.setNetworkAvailable(false);
@@ -2423,6 +2382,13 @@
         mUploadHandler.openFileChooser(uploadMsg, acceptType, capture);
     }
 
+    @Override
+    public void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
+                        boolean capture) {
+        mUploadHandler = new UploadHandler(this);
+        mUploadHandler.showFileChooser(uploadFilePaths, acceptTypes, capture);
+    }
+
     // thumbnails
 
     /**
diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java
index 8e8a5b7..f4d63d9 100644
--- a/src/com/android/browser/NavigationBarBase.java
+++ b/src/com/android/browser/NavigationBarBase.java
@@ -171,11 +171,9 @@
         stopEditingUrl();
         if (UrlInputView.TYPED.equals(source)) {
             String url = null;
-            Object[] params  = {new String("persist.env.browser.wap2estore"),
-                                    Boolean.valueOf(false)};
-            Class[] type = new Class[] {String.class, boolean.class};
-            Boolean wap2estore = (Boolean) ReflectHelper.invokeMethod(
-                      "android.os.SystemProperties", "getBoolean", type, params);
+            String browserRes =
+                getContext().getResources().getString(R.string.config_carrier_resource);
+            boolean wap2estore = "ct".equals(browserRes);
             if ((wap2estore && isEstoreTypeUrl(text)) || isRtspTypeUrl(text)
                 || isMakeCallTypeUrl(text)) {
                 url = text;
@@ -194,13 +192,15 @@
 
             // add for carrier wap2estore feature
             if (url != null && t != null && wap2estore && isEstoreTypeUrl(url)) {
-                handleEstoreTypeUrl(url);
-                setDisplayTitle(text);
-                return;
+                if (handleEstoreTypeUrl(url)) {
+                    setDisplayTitle(text);
+                    return;
+                }
             }
             // add for rtsp scheme feature
             if (url != null && t != null && isRtspTypeUrl(url)) {
                 if (handleRtspTypeUrl(url)) {
+                    setDisplayTitle(text);
                     return;
                 }
             }
@@ -263,36 +263,27 @@
     }
 
     private boolean isEstoreTypeUrl(String url) {
-        String utf8Url = null;
-        try {
-            utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "err " + e);
-        }
-        if (utf8Url != null && utf8Url.startsWith("estore:")) {
+        if (url != null && url.startsWith("estore:")) {
             return true;
         }
         return false;
     }
 
-    private void handleEstoreTypeUrl(String url) {
-        String utf8Url = null, finalUrl = null;
-        try {
-            utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "err " + e);
-        }
-        if (utf8Url != null) {
-            finalUrl = utf8Url;
-        } else {
-            finalUrl = url;
-        }
-        if (finalUrl.replaceFirst("estore:", "").length() > 256) {
+    private boolean handleEstoreTypeUrl(String url) {
+        if (url.getBytes().length > 256) {
             Toast.makeText(getContext(), R.string.estore_url_warning, Toast.LENGTH_LONG).show();
-            return;
+            return false;
         }
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setData(Uri.parse(finalUrl));
+
+        Intent intent;
+        // perform generic parsing of the URI to turn it into an Intent.
+        try {
+            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
+        } catch (URISyntaxException ex) {
+            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
+            return false;
+        }
+
         try {
             getContext().startActivity(intent);
         } catch (ActivityNotFoundException ex) {
@@ -300,6 +291,8 @@
             mUiController.loadUrl(mBaseUi.getActiveTab(), downloadUrl);
             Toast.makeText(getContext(), R.string.download_estore_app, Toast.LENGTH_LONG).show();
         }
+
+        return true;
     }
 
     private boolean isRtspTypeUrl(String url) {
diff --git a/src/com/android/browser/PreloadController.java b/src/com/android/browser/PreloadController.java
index 3290611..ebb3523 100644
--- a/src/com/android/browser/PreloadController.java
+++ b/src/com/android/browser/PreloadController.java
@@ -208,6 +208,12 @@
     }
 
     @Override
+    public void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
+            boolean capture) {
+        if (LOGD_ENABLED) Log.d(LOGTAG, "showFileChooser()");
+    }
+
+    @Override
     public void endActionMode() {
         if (LOGD_ENABLED) Log.d(LOGTAG, "endActionMode()");
     }
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 26f9152..1b0b68c 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -1030,6 +1030,16 @@
             }
         }
 
+        @Override
+        public void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
+                boolean capture) {
+            if (mInForeground) {
+                mWebViewController.showFileChooser(uploadFilePaths, acceptTypes, capture);
+            } else {
+                uploadFilePaths.onReceiveValue(null);
+            }
+        }
+
         /**
          * Deliver a list of already-visited URLs
          */
diff --git a/src/com/android/browser/UploadHandler.java b/src/com/android/browser/UploadHandler.java
index 349f67f..51ca7f9 100644
--- a/src/com/android/browser/UploadHandler.java
+++ b/src/com/android/browser/UploadHandler.java
@@ -18,12 +18,14 @@
 
 import android.app.Activity;
 import android.content.ActivityNotFoundException;
+import android.content.ContentResolver;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.Environment;
 import android.provider.MediaStore;
 import android.webkit.ValueCallback;
+import android.util.Log;
 import android.widget.Toast;
 
 import com.android.browser.R;
@@ -37,10 +39,12 @@
  */
 public class UploadHandler {
 
+    private static final String TAG = "UploadHandler";
     /*
      * The Object used to inform the WebView of the file to upload.
      */
     private ValueCallback<Uri> mUploadMessage;
+    private ValueCallback<String[]> mUploadFilePaths;
     private String mCameraFilePath;
 
     private boolean mHandled;
@@ -60,38 +64,6 @@
         return mHandled;
     }
 
-    private boolean isDrmFileUpload(Uri uri) {
-        if (uri == null) return false;
-
-        String path = null;
-        String scheme = uri.getScheme();
-        if ("content".equals(scheme)) {
-            String[] proj = null;
-            if (uri.toString().contains("/images/")) {
-                proj = new String[]{MediaStore.Images.Media.DATA};
-            } else if (uri.toString().contains("/audio/")) {
-                proj = new String[]{MediaStore.Audio.Media.DATA};
-            } else if (uri.toString().contains("/video/")) {
-                proj = new String[]{MediaStore.Video.Media.DATA};
-            }
-            Cursor cursor = mController.getActivity().managedQuery(uri, proj, null, null, null);
-            if (cursor != null && cursor.moveToFirst() && proj != null) {
-                path = cursor.getString(0);
-            }
-        } else if ("file".equals(scheme)) {
-            path = uri.getPath();
-        }
-        if (path != null) {
-            if (path.endsWith(".fl") || path.endsWith(".dm")
-                    || path.endsWith(".dcf") || path.endsWith(".dr") || path.endsWith(".dd")) {
-                Toast.makeText(mController.getContext(), R.string.drm_file_unsupported,
-                        Toast.LENGTH_LONG).show();
-                return true;
-            }
-        }
-        return false;
-    }
-
     void onResult(int resultCode, Intent intent) {
 
         if (resultCode == Activity.RESULT_CANCELED && mCaughtActivityNotFoundException) {
@@ -121,16 +93,59 @@
             }
         }
 
-        // add unsupport uploading drm file feature for carrier.
-        Object[] params  = {new String("persist.env.browser.drmupload"),
-                            Boolean.valueOf(false)};
-        Class[] type = new Class[] {String.class, boolean.class};
-        Boolean drmUpload = (Boolean) ReflectHelper.invokeMethod(
-                      "android.os.SystemProperties", "getBoolean", type, params);
-        if (drmUpload && isDrmFileUpload(result)) {
-            mUploadMessage.onReceiveValue(null);
-        } else {
-            mUploadMessage.onReceiveValue(result);
+        // try to get local file path from uri
+        boolean hasGoodFilePath = false;
+        String filePath = null;
+        if (result != null) {
+            String scheme = result.getScheme();
+            if ("file".equals(scheme)) {
+                filePath = result.getPath();
+                hasGoodFilePath = filePath != null && !filePath.isEmpty();
+            } else if ("content".equals(scheme)) {
+                ContentResolver cr = mController.getActivity().getContentResolver();
+                String[] projection = {"_data"};
+                Cursor c = cr.query(result, projection, null, null, null);
+                try {
+                    if (c != null && c.moveToFirst()) {
+                        filePath = c.getString(0);
+                        hasGoodFilePath = filePath != null && !filePath.isEmpty();
+                    }
+                } finally {
+                    if (c != null) {
+                        c.close();
+                    }
+                }
+            }
+        }
+
+        // Add for carrier feature - prevent uploading DRM type files.
+        String browserRes = mController.getActivity().getResources().
+                getString(R.string.config_carrier_resource);
+        boolean isDRMFileType = false;
+        if ("ct".equals(browserRes) && filePath != null
+                && (filePath.endsWith(".fl") || filePath.endsWith(".dm")
+                || filePath.endsWith(".dcf") || filePath.endsWith(".dr")
+                || filePath.endsWith(".dd"))) {
+            isDRMFileType = true;
+            Toast.makeText(mController.getContext(), R.string.drm_file_unsupported,
+                    Toast.LENGTH_LONG).show();
+        }
+
+        if (mUploadMessage != null) {
+            if (!isDRMFileType) {
+                mUploadMessage.onReceiveValue(result);
+            } else {
+                mUploadMessage.onReceiveValue(null);
+            }
+        }
+
+        if (mUploadFilePaths != null) {
+            if (hasGoodFilePath && !isDRMFileType) {
+                Log.d(TAG, "upload file path:" + filePath);
+                mUploadFilePaths.onReceiveValue(new String[]{filePath});
+            } else {
+                mUploadFilePaths.onReceiveValue(null);
+            }
         }
 
         mHandled = true;
@@ -238,6 +253,80 @@
         startActivity(createDefaultOpenableIntent());
     }
 
+    void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
+            boolean capture) {
+
+        final String imageMimeType = "image/*";
+        final String videoMimeType = "video/*";
+        final String audioMimeType = "audio/*";
+
+        if (mUploadFilePaths != null) {
+            // Already a file picker operation in progress.
+            return;
+        }
+
+        mUploadFilePaths = uploadFilePaths;
+
+        // Parse the accept type.
+        String params[] = acceptTypes.split(";");
+        String mimeType = params[0];
+
+        // Ensure it is not still set from a previous upload.
+        mCameraFilePath = null;
+
+        if (mimeType.equals(imageMimeType)) {
+            if (capture) {
+                // Specified 'image/*' and capture=true, so go ahead and launch the
+                // camera directly.
+                startActivity(createCameraIntent());
+                return;
+            } else {
+                // Specified just 'image/*', capture=false, or no capture value.
+                // In all these cases we show a traditional picker filetered on accept type
+                // so launch an intent for both the Camera and image/* OPENABLE.
+                Intent chooser = createChooserIntent(createCameraIntent());
+                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(imageMimeType));
+                startActivity(chooser);
+                return;
+            }
+        } else if (mimeType.equals(videoMimeType)) {
+            if (capture) {
+                // Specified 'video/*' and capture=true, so go ahead and launch the
+                // camcorder directly.
+                startActivity(createCamcorderIntent());
+                return;
+           } else {
+                // Specified just 'video/*', capture=false, or no capture value.
+                // In all these cases we show an intent for the traditional file picker, filtered
+                // on accept type so launch an intent for both camcorder and video/* OPENABLE.
+                Intent chooser = createChooserIntent(createCamcorderIntent());
+                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(videoMimeType));
+                startActivity(chooser);
+                return;
+            }
+        } else if (mimeType.equals(audioMimeType)) {
+            if (capture) {
+                // Specified 'audio/*' and capture=true, so go ahead and launch the sound
+                // recorder.
+                startActivity(createSoundRecorderIntent());
+                return;
+            } else {
+                // Specified just 'audio/*',  capture=false, or no capture value.
+                // In all these cases so go ahead and launch an intent for both the sound
+                // recorder and audio/* OPENABLE.
+                Intent chooser = createChooserIntent(createSoundRecorderIntent());
+                chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(audioMimeType));
+                startActivity(chooser);
+                return;
+            }
+        }
+
+        // No special handling based on the accept type was necessary, so trigger the default
+        // file upload chooser.
+        startActivity(createDefaultOpenableIntent());
+    }
+
+
     private void startActivity(Intent intent) {
         try {
             mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED);
diff --git a/src/com/android/browser/UrlHandler.java b/src/com/android/browser/UrlHandler.java
index 4b40df9..914edae 100755
--- a/src/com/android/browser/UrlHandler.java
+++ b/src/com/android/browser/UrlHandler.java
@@ -46,7 +46,7 @@
     /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
     /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
     /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
-
+    /* package */ final static String SCHEME_MAILTO = "mailto:";
     Controller mController;
     Activity mActivity;
 
@@ -103,14 +103,16 @@
             return true;
         }
 
-        // add for carrier wap2estore feature
-        Object[] params  = {new String("persist.env.browser.wap2estore"),
-                            Boolean.valueOf(false)};
-        Class[] type = new Class[] {String.class, boolean.class};
-        Boolean wap2estore = (Boolean)ReflectHelper.invokeMethod(
-                      "android.os.SystemProperties", "getBoolean", type, params);
-        if (wap2estore && isEstoreTypeUrl(url)) {
-            handleEstoreTypeUrl(url);
+        // add for carrier feature - recognize additional website format
+        // here add to support "mailto:" scheme
+        if (url.startsWith(SCHEME_MAILTO) && handleMailtoTypeUrl(url)) {
+            return true;
+        }
+
+        // add for carrier feature - wap2estore
+        String browserRes = mActivity.getResources().getString(R.string.config_carrier_resource);
+        boolean wap2estore = "ct".equals(browserRes);
+        if (wap2estore && isEstoreTypeUrl(url) && handleEstoreTypeUrl(url)) {
             return true;
         }
 
@@ -125,46 +127,54 @@
         return false;
     }
 
-    private boolean isEstoreTypeUrl(String url) {
-        String utf8Url = null;
+    private boolean handleMailtoTypeUrl(String url) {
+        Intent intent;
+        // perform generic parsing of the URI to turn it into an Intent.
         try {
-            utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "err " + e);
+            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
+            mActivity.startActivity(intent);
+        } catch (URISyntaxException ex) {
+            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
+            return false;
+        } catch (ActivityNotFoundException ex) {
+            Log.w("Browser", "No Activity Found for " + url);
+            return false;
         }
-        if (utf8Url != null && utf8Url.startsWith("estore:")) {
+
+        return true;
+    }
+
+    private boolean isEstoreTypeUrl(String url) {
+        if (url != null && url.startsWith("estore:")) {
             return true;
         }
         return false;
     }
 
-    private void handleEstoreTypeUrl(String url) {
-        String utf8Url = null, finalUrl = null;
-        try {
-            utf8Url = new String(url.getBytes("UTF-8"), "UTF-8");
-        } catch (UnsupportedEncodingException e) {
-            Log.e(TAG, "err " + e);
-        }
-        if (utf8Url != null) {
-            finalUrl = utf8Url;
-        } else {
-            finalUrl = url;
-        }
-        if (finalUrl.replaceFirst("estore:", "").length() > 256) {
+    private boolean handleEstoreTypeUrl(String url) {
+        if (url.getBytes().length > 256) {
             Toast.makeText(mActivity, R.string.estore_url_warning, Toast.LENGTH_LONG).show();
-            return;
+            return false;
         }
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setData(Uri.parse(finalUrl));
+
+        Intent intent;
+        // perform generic parsing of the URI to turn it into an Intent.
         try {
+            intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
             mActivity.startActivity(intent);
+        } catch (URISyntaxException ex) {
+            Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
+            return false;
         } catch (ActivityNotFoundException ex) {
             String downloadUrl = mActivity.getResources().getString(R.string.estore_homepage);
             mController.loadUrl(mController.getCurrentTab(), downloadUrl);
             Toast.makeText(mActivity, R.string.download_estore_app, Toast.LENGTH_LONG).show();
         }
+
+        return true;
     }
 
+
     boolean startActivityForUrl(Tab tab, String url) {
       Intent intent;
       // perform generic parsing of the URI to turn it into an Intent.
diff --git a/src/com/android/browser/WebViewController.java b/src/com/android/browser/WebViewController.java
index c5e3bc0..373d72c 100644
--- a/src/com/android/browser/WebViewController.java
+++ b/src/com/android/browser/WebViewController.java
@@ -96,6 +96,9 @@
 
     void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture);
 
+    void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
+            boolean capture);
+
     void endActionMode();
 
     void attachSubWindow(Tab tab);