1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.android_webview; 6 7import android.graphics.Bitmap; 8import android.os.AsyncTask; 9import android.util.Log; 10 11import org.chromium.base.ThreadUtils; 12 13import java.io.IOException; 14import java.io.InputStream; 15import java.io.OutputStream; 16import java.io.PipedInputStream; 17import java.io.PipedOutputStream; 18import java.util.Random; 19 20/** 21 * This class takes advantage of shouldInterceptRequest(), returns the bitmap from 22 * WebChromeClient.getDefaultVidoePoster() when the mDefaultVideoPosterURL is requested. 23 * 24 * The shouldInterceptRequest is used to get the default video poster, if the url is 25 * the mDefaultVideoPosterURL. 26 */ 27public class DefaultVideoPosterRequestHandler { 28 private static InputStream getInputStream(final AwContentsClient contentClient) 29 throws IOException { 30 final PipedInputStream inputStream = new PipedInputStream(); 31 final PipedOutputStream outputStream = new PipedOutputStream(inputStream); 32 33 // Send the request to UI thread to callback to the client, and if it provides a 34 // valid bitmap bounce on to the worker thread pool to compress it into the piped 35 // input/output stream. 36 ThreadUtils.runOnUiThread(new Runnable() { 37 @Override 38 public void run() { 39 final Bitmap defaultVideoPoster = contentClient.getDefaultVideoPoster(); 40 if (defaultVideoPoster == null) { 41 closeOutputStream(outputStream); 42 return; 43 } 44 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() { 45 @Override 46 public void run() { 47 try { 48 defaultVideoPoster.compress(Bitmap.CompressFormat.PNG, 100, 49 outputStream); 50 outputStream.flush(); 51 } catch (IOException e) { 52 Log.e(TAG, null, e); 53 } finally { 54 closeOutputStream(outputStream); 55 } 56 } 57 }); 58 } 59 }); 60 return inputStream; 61 } 62 63 private static void closeOutputStream(OutputStream outputStream) { 64 try { 65 outputStream.close(); 66 } catch (IOException e) { 67 Log.e(TAG, null, e); 68 } 69 } 70 71 private static final String TAG = "DefaultVideoPosterRequestHandler"; 72 private String mDefaultVideoPosterURL; 73 private AwContentsClient mContentClient; 74 75 public DefaultVideoPosterRequestHandler(AwContentsClient contentClient) { 76 mDefaultVideoPosterURL = generateDefaulVideoPosterURL(); 77 mContentClient = contentClient; 78 } 79 80 /** 81 * Used to get the image if the url is mDefaultVideoPosterURL. 82 * 83 * @param url the url requested 84 * @return AwWebResourceResponse which caller can get the image if the url is 85 * the default video poster URL, otherwise null is returned. 86 */ 87 public AwWebResourceResponse shouldInterceptRequest(final String url) { 88 if (!mDefaultVideoPosterURL.equals(url)) return null; 89 90 try { 91 return new AwWebResourceResponse("image/png", null, getInputStream(mContentClient)); 92 } catch (IOException e) { 93 Log.e(TAG, null, e); 94 return null; 95 } 96 } 97 98 public String getDefaultVideoPosterURL() { 99 return mDefaultVideoPosterURL; 100 } 101 102 /** 103 * @return a unique URL which has little chance to be used by application. 104 */ 105 private static String generateDefaulVideoPosterURL() { 106 Random randomGenerator = new Random(); 107 String path = String.valueOf(randomGenerator.nextLong()); 108 // The scheme of this URL should be kept in sync with kAndroidWebViewVideoPosterScheme 109 // on the native side (see android_webview/common/url_constants.h) 110 return "android-webview-video-poster:default_video_poster/" + path; 111 } 112} 113