@Override
 public boolean onJsBeforeUnload(WebView view, String url, String message, JsResult result) {
   if (originalWebChromeClient.onJsBeforeUnload(view, url, message, result)) {
     return originalWebChromeClient.onJsBeforeUnload(view, url, message, result);
   }
   return true;
 }
  @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();
  }
 @Override
 public void onGeolocationPermissionsShowPrompt(
     String origin, GeolocationPermissions.Callback callback) {
   if (originalWebChromeClient != null) {
     originalWebChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
   }
 }
 @Override
 public boolean onJsTimeout() {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.onJsTimeout();
   }
   return true;
 }
 @Override
 public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.onJsConfirm(view, url, message, result);
   }
   return true;
 }
 @Override
 public void onReachedMaxAppCacheSize(
     long requiredStorage, long quota, WebStorage.QuotaUpdater quotaUpdater) {
   if (originalWebChromeClient != null) {
     originalWebChromeClient.onReachedMaxAppCacheSize(requiredStorage, quota, quotaUpdater);
   }
 }
 @Override
 public Bitmap getDefaultVideoPoster() {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.getDefaultVideoPoster();
   }
   return null;
 }
 @Override
 public View getVideoLoadingProgressView() {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.getVideoLoadingProgressView();
   }
   return null;
 }
 @Override
 public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.onConsoleMessage(consoleMessage);
   }
   return true;
 }
 @Override
 public boolean onCreateWindow(
     WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
   if (originalWebChromeClient != null) {
     return originalWebChromeClient.onCreateWindow(view, isDialog, isUserGesture, resultMsg);
   }
   return true;
 }
 @Override
 public void onProgressChanged(final WebView view, final int newProgress) {
   super.onProgressChanged(view, newProgress);
   BWebHost webHost = webView.getWebHost();
   if (webHost != null) {
     webHost.postMessage(BConstants.MSG_PAGE_UPDATE, 0, null);
   }
 }
  @Override
  public void onShowCustomView(View view, CustomViewCallback callback) {
    super.onShowCustomView(view, callback);
    // Android SDK版本
    if (Build.VERSION.SDK_INT >= 14) {

      if (view instanceof FrameLayout) {
        FrameLayout frameLayout = (FrameLayout) view; // A video wants to be shown
        View focusedChild = frameLayout.getFocusedChild();
        this.isVideoFullscreen = true;
        this.videoViewContainer = frameLayout;
        this.videoViewCallback = callback;
        activityNonVideoView.setVisibility(View.GONE); // 隐藏掉视频所在布局中除了用来展示全屏视频以外的布局
        activityVideoView.addView(
            videoViewContainer,
            new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        activityVideoView.setVisibility(View.VISIBLE); // 设置全屏布局可见
        ((Activity) activityVideoView.getContext())
            .setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); // 强制当前页面在手机中横屏
        if (focusedChild instanceof VideoView) { // VideoView (typically API level <11)
          VideoView videoView = (VideoView) focusedChild;
          videoView.setOnPreparedListener(this); // Handle all the required events
          videoView.setOnCompletionListener(this);
          videoView.setOnErrorListener(this);
        } else {
          // Usually android.webkit.HTML5VideoFullScreen$VideoSurfaceView, sometimes
          // android.webkit.HTML5VideoFullScreen$VideoTextureView
          // HTML5VideoFullScreen (typically API level 11+)
          // Handle HTML5 video ended event
          if (webView != null && webView.getSettings().getJavaScriptEnabled()) {
            // Run javascript code that detects the video end and notifies the interface
            String js = "javascript:";
            js += "_ytrp_html5_video = document.getElementsByTagName('video')[0];";
            js += "if (_ytrp_html5_video !== undefined) {";
            {
              js += "function _ytrp_html5_video_ended() {";
              {
                js += "_ytrp_html5_video.removeEventListener('ended', _ytrp_html5_video_ended);";
                js +=
                    "_VideoEnabledWebView.notifyVideoEnd();"; // Must match Javascript interface
                                                              // name and method of
                                                              // VideoEnableWebView
              }
              js += "}";
              js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";
            }
            js += "}";
            webView.loadUrl(js);
          }
        }

        // Notify full-screen change
        if (toggledFullscreenCallback != null) {
          toggledFullscreenCallback.toggledFullscreen(true);
        }
      }
    }
  }
 /** @see AwContentsClient#onProgressChanged(int) */
 @Override
 public void onProgressChanged(int progress) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onProgressChanged=" + progress);
     mWebChromeClient.onProgressChanged(mWebView, progress);
   }
   TraceEvent.end();
 }
 @Override
 public void onShowCustomView(View view, CustomViewCallback cb) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onShowCustomView");
     mWebChromeClient.onShowCustomView(view, cb);
   }
   TraceEvent.end();
 }
 public void onConsoleMessage(String paramString1, int paramInt, String paramString2) {
   if (Build.VERSION.SDK_INT == 7) {
     LOG.d(
         TAG,
         "%s: Line %d : %s",
         new Object[] {paramString2, Integer.valueOf(paramInt), paramString1});
     super.onConsoleMessage(paramString1, paramInt, paramString2);
   }
 }
 /** @see AwContentsClient#onReceivedIcon(Bitmap bitmap) */
 @Override
 public void onReceivedIcon(Bitmap bitmap) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onReceivedIcon");
     mWebChromeClient.onReceivedIcon(mWebView, bitmap);
   }
   TraceEvent.end();
 }
 /** @see AwContentsClient#getVisitedHistory */
 @Override
 public void getVisitedHistory(ValueCallback<String[]> callback) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "getVisitedHistory");
     mWebChromeClient.getVisitedHistory(callback);
   }
   TraceEvent.end();
 }
 /** @see AwContentsClient#onCloseWindow() */
 @Override
 public void onCloseWindow() {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onCloseWindow");
     mWebChromeClient.onCloseWindow(mWebView);
   }
   TraceEvent.end();
 }
 // console.log in api level 7: http://developer.android.com/guide/developing/debug-tasks.html
 // Expect this to not compile in a future Android release!
 @SuppressWarnings("deprecation")
 @Override
 public void onConsoleMessage(String message, int lineNumber, String sourceID) {
   // This is only for Android 2.1
   if (android.os.Build.VERSION.SDK_INT == android.os.Build.VERSION_CODES.ECLAIR_MR1) {
     LOG.d(TAG, "%s: Line %d : %s", sourceID, lineNumber, message);
     super.onConsoleMessage(message, lineNumber, sourceID);
   }
 }
 /** @see AwContentsClient#onReceivedTouchIconUrl(String url, boolean precomposed) */
 @Override
 public void onReceivedTouchIconUrl(String url, boolean precomposed) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onReceivedTouchIconUrl=" + url);
     mWebChromeClient.onReceivedTouchIconUrl(mWebView, url, precomposed);
   }
   TraceEvent.end();
 }
 /** @see AwContentsClient#onRequestFocus() */
 @Override
 public void onRequestFocus() {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onRequestFocus");
     mWebChromeClient.onRequestFocus(mWebView);
   }
   TraceEvent.end();
 }
 @Override
 public void onHideCustomView() {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onHideCustomView");
     mWebChromeClient.onHideCustomView();
   }
   TraceEvent.end();
 }
 /** @see ContentViewClient#onReceivedTitle(String) */
 @Override
 public void onReceivedTitle(String title) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onReceivedTitle");
     mWebChromeClient.onReceivedTitle(mWebView, title);
   }
   TraceEvent.end();
 }
 @Override
 public void onGeolocationPermissionsHidePrompt() {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onGeolocationPermissionsHidePrompt");
     mWebChromeClient.onGeolocationPermissionsHidePrompt();
   }
   TraceEvent.end();
 }
 @Override
 public void onProgressChanged(WebView view, int newProgress) {
   super.onProgressChanged(view, newProgress);
   mProgressbar.setProgress(newProgress);
   if (newProgress == 100) {
     mProgressbar.setVisibility(View.GONE);
   } else {
     mProgressbar.setVisibility(View.VISIBLE);
   }
 }
 @Override
 public void onProgressChanged(WebView view, int newProgress) {
   if (newProgress == 100) {
     progressbar.setVisibility(GONE);
   } else {
     if (progressbar.getVisibility() == GONE) progressbar.setVisibility(VISIBLE);
     progressbar.setProgress(newProgress);
   }
   super.onProgressChanged(view, newProgress);
 }
 @Override
 public void onGeolocationPermissionsShowPrompt(
     String origin, GeolocationPermissions.Callback callback) {
   TraceEvent.begin();
   if (mWebChromeClient != null) {
     if (TRACE) Log.d(TAG, "onGeolocationPermissionsShowPrompt");
     mWebChromeClient.onGeolocationPermissionsShowPrompt(origin, callback);
   }
   TraceEvent.end();
 }
 @Override
 public void onExceededDatabaseQuota(
     String url,
     String databaseIdentifier,
     long currentQuota,
     long estimatedSize,
     long totalUsedQuota,
     QuotaUpdater quotaUpdater) {
   super.onExceededDatabaseQuota(
       url, databaseIdentifier, currentQuota, estimatedSize, totalUsedQuota, quotaUpdater);
 }
 @Override
 /**
  * Instructs the client to show a prompt to ask the user to set the Geolocation permission state
  * for the specified origin.
  *
  * @param origin
  * @param callback
  */
 public void onGeolocationPermissionsShowPrompt(String origin, Callback callback) {
   super.onGeolocationPermissionsShowPrompt(origin, callback);
   callback.invoke(origin, true, false);
 }
 @Override
 public void onExceededDatabaseQuota(
     String url,
     String databaseIdentifier,
     long quota,
     long estimatedDatabaseSize,
     long totalQuota,
     WebStorage.QuotaUpdater quotaUpdater) {
   if (originalWebChromeClient != null) {
     originalWebChromeClient.onExceededDatabaseQuota(
         url, databaseIdentifier, quota, estimatedDatabaseSize, totalQuota, quotaUpdater);
   }
 }