1// Copyright (c) 2012 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 org.chromium.base.CalledByNative; 8import org.chromium.base.JNINamespace; 9 10import android.content.res.Resources; 11 12import java.io.IOException; 13import java.io.InputStream; 14import java.io.InputStreamReader; 15import java.lang.ref.SoftReference; 16import java.util.HashMap; 17import java.util.Map; 18import java.util.NoSuchElementException; 19import java.util.Scanner; 20 21@JNINamespace("android_webview::AwResource") 22public class AwResource { 23 // The following resource ID's must be initialized by the embedder. 24 25 // Raw resource ID for an HTML page to be displayed in the case of 26 // a specific load error. 27 public static int RAW_LOAD_ERROR; 28 29 // Raw resource ID for an HTML page to be displayed in the case of 30 // a generic load error. (It's called NO_DOMAIN for legacy reasons). 31 public static int RAW_NO_DOMAIN; 32 33 // String resource ID for the default text encoding to use. 34 public static int STRING_DEFAULT_TEXT_ENCODING; 35 36 // The embedder should inject a Resources object that will be used 37 // to resolve Resource IDs into the actual resources. 38 private static Resources sResources; 39 40 // Loading some resources is expensive, so cache the results. 41 private static Map<Integer, SoftReference<String> > sResourceCache; 42 43 private static final int TYPE_STRING = 0; 44 private static final int TYPE_RAW = 1; 45 46 public static void setResources(Resources resources) { 47 sResources = resources; 48 sResourceCache = new HashMap<Integer, SoftReference<String> >(); 49 } 50 51 @CalledByNative 52 public static String getDefaultTextEncoding() { 53 return getResource(STRING_DEFAULT_TEXT_ENCODING, TYPE_STRING); 54 } 55 56 @CalledByNative 57 public static String getNoDomainPageContent() { 58 return getResource(RAW_NO_DOMAIN, TYPE_RAW); 59 } 60 61 @CalledByNative 62 public static String getLoadErrorPageContent() { 63 return getResource(RAW_LOAD_ERROR, TYPE_RAW); 64 } 65 66 private static String getResource(int resid, int type) { 67 assert resid != 0; 68 assert sResources != null; 69 assert sResourceCache != null; 70 71 String result = sResourceCache.get(resid) == null ? 72 null : sResourceCache.get(resid).get(); 73 if (result == null) { 74 switch (type) { 75 case TYPE_STRING: 76 result = sResources.getString(resid); 77 break; 78 case TYPE_RAW: 79 result = getRawFileResourceContent(resid); 80 break; 81 default: 82 throw new IllegalArgumentException("Unknown resource type"); 83 } 84 85 sResourceCache.put(resid, new SoftReference<String>(result)); 86 } 87 return result; 88 } 89 90 private static String getRawFileResourceContent(int resid) { 91 assert resid != 0; 92 assert sResources != null; 93 94 InputStreamReader isr = null; 95 String result = null; 96 97 try { 98 isr = new InputStreamReader( 99 sResources.openRawResource(resid)); 100 // \A tells the scanner to use the beginning of the input 101 // as the delimiter, hence causes it to read the entire text. 102 result = new Scanner(isr).useDelimiter("\\A").next(); 103 } catch (Resources.NotFoundException e) { 104 return ""; 105 } catch (NoSuchElementException e) { 106 return ""; 107 } 108 finally { 109 try { 110 if (isr != null) { 111 isr.close(); 112 } 113 } catch(IOException e) { 114 } 115 } 116 return result; 117 } 118} 119