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