blob: 3b3b3265f491eb05273b71213f96f6dbff091bbe [file] [log] [blame]
// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.android_webview;
import android.content.res.Resources;
import android.util.SparseArray;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.ref.SoftReference;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
* A class that defines a set of resource IDs and functionality to resolve
* those IDs to concrete resources.
*/
@JNINamespace("android_webview::AwResource")
public class AwResource {
// The following resource ID's must be initialized by the embedder.
// Raw resource ID for an HTML page to be displayed in the case of
// a specific load error.
private static int RAW_LOAD_ERROR;
// Raw resource ID for an HTML page to be displayed in the case of
// a generic load error. (It's called NO_DOMAIN for legacy reasons).
private static int RAW_NO_DOMAIN;
// String resource ID for the default text encoding to use.
private static int STRING_DEFAULT_TEXT_ENCODING;
// Array resource ID for the configuration of platform specific key-systems.
private static int STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING;
// The embedder should inject a Resources object that will be used
// to resolve Resource IDs into the actual resources.
private static Resources sResources;
// Loading some resources is expensive, so cache the results.
private static SparseArray<SoftReference<String>> sResourceCache;
private static final int TYPE_STRING = 0;
private static final int TYPE_RAW = 1;
public static void setResources(Resources resources) {
sResources = resources;
sResourceCache = new SparseArray<SoftReference<String>>();
}
public static void setErrorPageResources(int loaderror, int nodomain) {
RAW_LOAD_ERROR = loaderror;
RAW_NO_DOMAIN = nodomain;
}
public static void setDefaultTextEncoding(int encoding) {
STRING_DEFAULT_TEXT_ENCODING = encoding;
}
public static void setConfigKeySystemUuidMapping(int config) {
STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING = config;
}
@CalledByNative
public static String getDefaultTextEncoding() {
return getResource(STRING_DEFAULT_TEXT_ENCODING, TYPE_STRING);
}
@CalledByNative
public static String getNoDomainPageContent() {
return getResource(RAW_NO_DOMAIN, TYPE_RAW);
}
@CalledByNative
public static String getLoadErrorPageContent() {
return getResource(RAW_LOAD_ERROR, TYPE_RAW);
}
public static String[] getConfigKeySystemUuidMapping() {
// No need to cache, since this should be called only once.
return sResources.getStringArray(STRING_ARRAY_CONFIG_KEY_SYSTEM_UUID_MAPPING);
}
private static String getResource(int resid, int type) {
assert resid != 0;
assert sResources != null;
assert sResourceCache != null;
SoftReference<String> stringRef = sResourceCache.get(resid);
String result = stringRef == null ? null : stringRef.get();
if (result == null) {
switch (type) {
case TYPE_STRING:
result = sResources.getString(resid);
break;
case TYPE_RAW:
result = getRawFileResourceContent(resid);
break;
default:
throw new IllegalArgumentException("Unknown resource type");
}
sResourceCache.put(resid, new SoftReference<String>(result));
}
return result;
}
private static String getRawFileResourceContent(int resid) {
assert resid != 0;
assert sResources != null;
InputStreamReader isr = null;
String result = null;
try {
isr = new InputStreamReader(
sResources.openRawResource(resid));
// \A tells the scanner to use the beginning of the input
// as the delimiter, hence causes it to read the entire text.
result = new Scanner(isr).useDelimiter("\\A").next();
} catch (Resources.NotFoundException e) {
return "";
} catch (NoSuchElementException e) {
return "";
} finally {
try {
if (isr != null) {
isr.close();
}
} catch (IOException e) {
// Nothing to do if close() fails.
}
}
return result;
}
}