[Android WebView] Support for fetching Android Java resources.
Add AwResource.java, a class that defines a set of resource IDs and functionality to resolve those IDs to concrete resources. Initially, we add three resources - two raw resources to represent error pags and a string resource for default text encoding. The embedder should set up the IDs before starting to use Chromium. Review URL: https://codereview.chromium.org/11145026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162205 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
android_webview
android_webview.gyp
common
java
src
org
chromium
android_webview
javatests
res
src
org
chromium
android_webview
native
renderer
@ -27,6 +27,7 @@
|
||||
'common/android_webview_message_generator.h',
|
||||
'common/aw_content_client.cc',
|
||||
'common/aw_content_client.h',
|
||||
'common/aw_resource.h',
|
||||
'common/render_view_messages.cc',
|
||||
'common/render_view_messages.h',
|
||||
'common/url_constants.cc',
|
||||
|
22
android_webview/common/aw_resource.h
Normal file
22
android_webview/common/aw_resource.h
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#ifndef ANDROID_WEBVIEW_COMMON_AW_RESOURCE_H_
|
||||
#define ANDROID_WEBVIEW_COMMON_AW_RESOURCE_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
// android_webview implements these with a JNI call to the
|
||||
// AwResource Java class.
|
||||
namespace android_webview {
|
||||
namespace AwResource {
|
||||
|
||||
std::string GetLoadErrorPageContent();
|
||||
std::string GetNoDomainPageContent();
|
||||
std::string GetDefaultTextEncoding();
|
||||
|
||||
} // namespace AwResource
|
||||
} // namsespace android_webview
|
||||
|
||||
#endif // ANDROID_WEBVIEW_COMMON_AW_RESOURCE_H_
|
@ -0,0 +1,118 @@
|
||||
// Copyright (c) 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 org.chromium.base.CalledByNative;
|
||||
import org.chromium.base.JNINamespace;
|
||||
|
||||
import android.content.res.Resources;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Scanner;
|
||||
|
||||
@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.
|
||||
public 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).
|
||||
public static int RAW_NO_DOMAIN;
|
||||
|
||||
// String resource ID for the default text encoding to use.
|
||||
public static int STRING_DEFAULT_TEXT_ENCODING;
|
||||
|
||||
// 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 Map<Integer, 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 HashMap<Integer, SoftReference<String> >();
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
private static String getResource(int resid, int type) {
|
||||
assert resid != 0;
|
||||
assert sResources != null;
|
||||
assert sResourceCache != null;
|
||||
|
||||
String result = sResourceCache.get(resid) == null ?
|
||||
null : sResourceCache.get(resid).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) {
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
BIN
android_webview/javatests/res/drawable/resource_icon.png
Normal file
BIN
android_webview/javatests/res/drawable/resource_icon.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 13 KiB |
5
android_webview/javatests/res/raw/blank_html.html
Normal file
5
android_webview/javatests/res/raw/blank_html.html
Normal file
@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>This page intentionally left blank.</title>
|
||||
</head>
|
||||
</html>
|
11
android_webview/javatests/res/values/strings.xml
Normal file
11
android_webview/javatests/res/values/strings.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!--
|
||||
Copyright (c) 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.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="test_string">Hello, World!</string>
|
||||
</resources>
|
@ -48,6 +48,7 @@ public class AndroidWebViewTestBase
|
||||
getInstrumentation().runOnMainSync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
AwTestResourceProvider.registerResources(context);
|
||||
ContentViewCore.initChromiumBrowserProcess(
|
||||
context, ContentView.MAX_RENDERERS_SINGLE_PROCESS);
|
||||
}
|
||||
|
35
android_webview/javatests/src/org/chromium/android_webview/test/AwTestResourceProvider.java
Normal file
35
android_webview/javatests/src/org/chromium/android_webview/test/AwTestResourceProvider.java
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 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.test;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import org.chromium.android_webview.AwResource;
|
||||
import org.chromium.content.app.AppResource;
|
||||
|
||||
public class AwTestResourceProvider {
|
||||
private static boolean sInitialized;
|
||||
|
||||
static void registerResources(Context context) {
|
||||
if (sInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
AppResource.DRAWABLE_ICON_ACTION_BAR_SHARE = R.drawable.resource_icon;
|
||||
AppResource.DRAWABLE_ICON_ACTION_BAR_WEB_SEARCH = R.drawable.resource_icon;
|
||||
|
||||
AppResource.STRING_ACTION_BAR_SHARE = R.string.test_string;
|
||||
AppResource.STRING_ACTION_BAR_WEB_SEARCH = R.string.test_string;
|
||||
|
||||
AwResource.setResources(context.getResources());
|
||||
|
||||
AwResource.RAW_LOAD_ERROR = R.raw.blank_html;
|
||||
AwResource.RAW_NO_DOMAIN = R.raw.blank_html;
|
||||
|
||||
AwResource.STRING_DEFAULT_TEXT_ENCODING = R.string.test_string;
|
||||
|
||||
sInitialized = true;
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@
|
||||
#include "android_webview/native/aw_contents.h"
|
||||
#include "android_webview/native/aw_contents_io_thread_client_impl.h"
|
||||
#include "android_webview/native/aw_http_auth_handler.h"
|
||||
#include "android_webview/native/aw_resource.h"
|
||||
#include "android_webview/native/cookie_manager.h"
|
||||
#include "android_webview/native/intercepted_request_data_impl.h"
|
||||
#include "android_webview/native/js_result_handler.h"
|
||||
@ -33,6 +34,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
|
||||
{ "AwContents", RegisterAwContents },
|
||||
{ "AwContentsIoThreadClientImpl", RegisterAwContentsIoThreadClientImpl},
|
||||
{ "AwHttpAuthHandler", RegisterAwHttpAuthHandler },
|
||||
{ "AwResource", AwResource::RegisterAwResource },
|
||||
{ "CookieManager", RegisterCookieManager },
|
||||
{ "InterceptedRequestDataImpl", RegisterInterceptedRequestData },
|
||||
{ "JsResultHandler", RegisterJsResultHandler },
|
||||
|
45
android_webview/native/aw_resource.cc
Normal file
45
android_webview/native/aw_resource.cc
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#include "android_webview/native/aw_resource.h"
|
||||
|
||||
#include "base/android/jni_string.h"
|
||||
#include "base/android/scoped_java_ref.h"
|
||||
#include "jni/AwResource_jni.h"
|
||||
|
||||
namespace android_webview {
|
||||
namespace AwResource {
|
||||
|
||||
// These JNI functions are used by the Renderer but rely on Java data
|
||||
// structures that exist in the Browser. By virtue of the WebView running
|
||||
// in single process we can just reach over and use them. When WebView is
|
||||
// multi-process capable, we'll need to rethink these. See crbug.com/156062.
|
||||
|
||||
std::string GetLoadErrorPageContent() {
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
ScopedJavaLocalRef<jstring> content =
|
||||
Java_AwResource_getLoadErrorPageContent(env);
|
||||
return base::android::ConvertJavaStringToUTF8(content);
|
||||
}
|
||||
|
||||
std::string GetNoDomainPageContent() {
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
ScopedJavaLocalRef<jstring> content =
|
||||
Java_AwResource_getNoDomainPageContent(env);
|
||||
return base::android::ConvertJavaStringToUTF8(content);
|
||||
}
|
||||
|
||||
std::string GetDefaultTextEncoding() {
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
ScopedJavaLocalRef<jstring> encoding =
|
||||
Java_AwResource_getDefaultTextEncoding(env);
|
||||
return base::android::ConvertJavaStringToUTF8(encoding);
|
||||
}
|
||||
|
||||
bool RegisterAwResource(JNIEnv* env) {
|
||||
return RegisterNativesImpl(env) >= 0;
|
||||
}
|
||||
|
||||
} // namespace AwResource
|
||||
} // namespace android_webview
|
20
android_webview/native/aw_resource.h
Normal file
20
android_webview/native/aw_resource.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
#ifndef ANDROID_WEBVIEW_NATIVE_AW_RESOURCE_H_
|
||||
#define ANDROID_WEBVIEW_NATIVE_AW_RESOURCE_H_
|
||||
|
||||
#include "base/android/jni_android.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace android_webview {
|
||||
namespace AwResource {
|
||||
|
||||
bool RegisterAwResource(JNIEnv* env);
|
||||
|
||||
} // namespace AwResource
|
||||
} // namsespace android_webview
|
||||
|
||||
#endif // ANDROID_WEBVIEW_NATIVE_AW_RESOURCE_H_
|
@ -39,6 +39,8 @@
|
||||
'aw_http_auth_handler.h',
|
||||
'aw_javascript_dialog_creator.cc',
|
||||
'aw_javascript_dialog_creator.h',
|
||||
'aw_resource.h',
|
||||
'aw_resource.cc',
|
||||
'aw_web_contents_delegate.cc',
|
||||
'aw_web_contents_delegate.h',
|
||||
'cookie_manager.cc',
|
||||
@ -68,6 +70,7 @@
|
||||
'../java/src/org/chromium/android_webview/AwContents.java',
|
||||
'../java/src/org/chromium/android_webview/AwContentsIoThreadClient.java',
|
||||
'../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
|
||||
'../java/src/org/chromium/android_webview/AwResource.java',
|
||||
'../java/src/org/chromium/android_webview/CookieManager.java',
|
||||
'../java/src/org/chromium/android_webview/InterceptedRequestData.java',
|
||||
'../java/src/org/chromium/android_webview/JsResultHandler.java',
|
||||
|
@ -4,11 +4,16 @@
|
||||
|
||||
#include "android_webview/renderer/aw_content_renderer_client.h"
|
||||
|
||||
#include "android_webview/common/aw_resource.h"
|
||||
#include "android_webview/common/url_constants.h"
|
||||
#include "android_webview/renderer/aw_render_view_ext.h"
|
||||
#include "base/utf_string_conversions.h"
|
||||
#include "content/public/renderer/render_thread.h"
|
||||
#include "googleurl/src/gurl.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
|
||||
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
|
||||
|
||||
namespace android_webview {
|
||||
@ -35,8 +40,7 @@ void AwContentRendererClient::RenderViewCreated(
|
||||
}
|
||||
|
||||
std::string AwContentRendererClient::GetDefaultEncoding() {
|
||||
// TODO(boliu): query android system locale.
|
||||
return std::string("ISO-8859-1");
|
||||
return AwResource::GetDefaultTextEncoding();
|
||||
}
|
||||
|
||||
WebKit::WebPlugin* AwContentRendererClient::CreatePluginReplacement(
|
||||
@ -49,8 +53,7 @@ WebKit::WebPlugin* AwContentRendererClient::CreatePluginReplacement(
|
||||
|
||||
bool AwContentRendererClient::HasErrorPage(int http_status_code,
|
||||
std::string* error_domain) {
|
||||
// TODO(boliu): Implement our own error pages.
|
||||
return false;
|
||||
return http_status_code >= 400;
|
||||
}
|
||||
|
||||
void AwContentRendererClient::GetNavigationErrorStrings(
|
||||
@ -58,7 +61,21 @@ void AwContentRendererClient::GetNavigationErrorStrings(
|
||||
const WebKit::WebURLError& error,
|
||||
std::string* error_html,
|
||||
string16* error_description) {
|
||||
// TODO(boliu): Implement our own error pages.
|
||||
if (error_html) {
|
||||
GURL error_url(failed_request.url());
|
||||
std::string err = UTF16ToUTF8(error.localizedDescription);
|
||||
std::string contents;
|
||||
if (err.empty()) {
|
||||
contents = AwResource::GetNoDomainPageContent();
|
||||
} else {
|
||||
contents = AwResource::GetLoadErrorPageContent();
|
||||
ReplaceSubstringsAfterOffset(&contents, 0, "%e", err);
|
||||
}
|
||||
|
||||
ReplaceSubstringsAfterOffset(&contents, 0, "%s",
|
||||
error_url.possibly_invalid_spec());
|
||||
*error_html = contents;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long AwContentRendererClient::VisitedLinkHash(
|
||||
|
Reference in New Issue
Block a user