@Override
  public void showFileChooser(
      final ValueCallback<String[]> uploadFileCallback,
      final AwContentsClient.FileChooserParams fileChooserParams) {
    if (mWebChromeClient == null) {
      uploadFileCallback.onReceiveValue(null);
      return;
    }
    TraceEvent.begin();
    FileChooserParamsAdapter adapter =
        new FileChooserParamsAdapter(fileChooserParams, mWebView.getContext());
    if (TRACE) Log.d(TAG, "showFileChooser");
    ValueCallback<Uri[]> callbackAdapter =
        new ValueCallback<Uri[]>() {
          private boolean mCompleted;

          @Override
          public void onReceiveValue(Uri[] uriList) {
            if (mCompleted) {
              throw new IllegalStateException("showFileChooser result was already called");
            }
            mCompleted = true;
            String s[] = null;
            if (uriList != null) {
              s = new String[uriList.length];
              for (int i = 0; i < uriList.length; i++) {
                s[i] = uriList[i].toString();
              }
            }
            uploadFileCallback.onReceiveValue(s);
          }
        };
    if (mWebChromeClient.onShowFileChooser(mWebView, callbackAdapter, adapter)) {
      return;
    }
    if (mWebView.getContext().getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.KITKAT) {
      uploadFileCallback.onReceiveValue(null);
      return;
    }
    ValueCallback<Uri> innerCallback =
        new ValueCallback<Uri>() {
          private boolean mCompleted;

          @Override
          public void onReceiveValue(Uri uri) {
            if (mCompleted) {
              throw new IllegalStateException("showFileChooser result was already called");
            }
            mCompleted = true;
            uploadFileCallback.onReceiveValue(uri == null ? null : new String[] {uri.toString()});
          }
        };
    if (TRACE) Log.d(TAG, "openFileChooser");
    mWebChromeClient.openFileChooser(
        innerCallback, fileChooserParams.acceptTypes, fileChooserParams.capture ? "*" : "");
    TraceEvent.end();
  }