Commit 015fd3d0 authored by Clark DuVall's avatar Clark DuVall Committed by Commit Bot

[WebLayer] Enforce matching version between client and impl

This checks the version of the client and impl code, and throws an
exception if they are not the same.

Change-Id: I64b0d3a47a88d8490ac5fb1c174ad6fe4d9204a8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1829915Reviewed-by: default avatarJohn Abd-El-Malek <jam@chromium.org>
Commit-Queue: Clark DuVall <cduvall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#702520}
parent adf14bb4
...@@ -46,6 +46,7 @@ generate_jni("jni") { ...@@ -46,6 +46,7 @@ generate_jni("jni") {
android_library("client_java") { android_library("client_java") {
java_files = [ java_files = [
"org/chromium/weblayer_private/aidl/ObjectWrapper.java", "org/chromium/weblayer_private/aidl/ObjectWrapper.java",
"org/chromium/weblayer_private/aidl/WebLayerVersion.java",
"org/chromium/weblayer_private/aidl/APICallException.java", "org/chromium/weblayer_private/aidl/APICallException.java",
] ]
......
...@@ -22,6 +22,7 @@ import org.chromium.weblayer_private.aidl.IObjectWrapper; ...@@ -22,6 +22,7 @@ import org.chromium.weblayer_private.aidl.IObjectWrapper;
import org.chromium.weblayer_private.aidl.IProfile; import org.chromium.weblayer_private.aidl.IProfile;
import org.chromium.weblayer_private.aidl.IWebLayer; import org.chromium.weblayer_private.aidl.IWebLayer;
import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper;
import org.chromium.weblayer_private.aidl.WebLayerVersion;
@UsedByReflection("WebLayer") @UsedByReflection("WebLayer")
public final class WebLayerImpl extends IWebLayer.Stub { public final class WebLayerImpl extends IWebLayer.Stub {
...@@ -38,6 +39,14 @@ public final class WebLayerImpl extends IWebLayer.Stub { ...@@ -38,6 +39,14 @@ public final class WebLayerImpl extends IWebLayer.Stub {
private WebLayerImpl() {} private WebLayerImpl() {}
/**
* Returns true if the client and implementation versions are compatible.
*/
@UsedByReflection("WebLayer")
public static boolean checkVersion(int clientVersion) {
return clientVersion == WebLayerVersion.sVersionNumber;
}
@Override @Override
public IProfile createProfile(String path) { public IProfile createProfile(String path) {
return new ProfileImpl(path); return new ProfileImpl(path);
......
// Copyright 2019 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.weblayer_private.aidl;
/** Holds the current version number of WebLayer. */
public final class WebLayerVersion { public static int sVersionNumber = 1; }
...@@ -35,6 +35,7 @@ android_library("java") { ...@@ -35,6 +35,7 @@ android_library("java") {
"org/chromium/weblayer/Profile.java", "org/chromium/weblayer/Profile.java",
"org/chromium/weblayer/WebLayer.java", "org/chromium/weblayer/WebLayer.java",
"org/chromium/weblayer/ChildProcessService.java", "org/chromium/weblayer/ChildProcessService.java",
"org/chromium/weblayer/UnsupportedVersionException.java",
] ]
deps = [ deps = [
......
// Copyright 2019 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.weblayer;
/**
* Error thrown if client and implementation versions are not compatible.
*/
public class UnsupportedVersionException extends Exception {
/**
* Constructs a new exception with the specified version.
*/
public UnsupportedVersionException(int clientVersion) {
super("Unsupported WebLayer version, client version " + clientVersion
+ " is not supported by the implementation.");
}
}
...@@ -23,6 +23,7 @@ import android.webkit.WebViewFactory; ...@@ -23,6 +23,7 @@ import android.webkit.WebViewFactory;
import org.chromium.weblayer_private.aidl.APICallException; import org.chromium.weblayer_private.aidl.APICallException;
import org.chromium.weblayer_private.aidl.IWebLayer; import org.chromium.weblayer_private.aidl.IWebLayer;
import org.chromium.weblayer_private.aidl.ObjectWrapper; import org.chromium.weblayer_private.aidl.ObjectWrapper;
import org.chromium.weblayer_private.aidl.WebLayerVersion;
import java.io.File; import java.io.File;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
...@@ -45,7 +46,8 @@ public final class WebLayer { ...@@ -45,7 +46,8 @@ public final class WebLayer {
* Loads the WebLayer implementation and returns the IWebLayer. This does *not* trigger the * Loads the WebLayer implementation and returns the IWebLayer. This does *not* trigger the
* implementation to start. * implementation to start.
*/ */
private static IWebLayer connectToWebLayerImplementation(Application application) { private static IWebLayer connectToWebLayerImplementation(Application application)
throws UnsupportedVersionException {
try { try {
// TODO: Make asset loading work on L, where WebViewDelegate doesn't exist. // TODO: Make asset loading work on L, where WebViewDelegate doesn't exist.
// WebViewDelegate.addWebViewAssetPath() accesses the currently loaded package info from // WebViewDelegate.addWebViewAssetPath() accesses the currently loaded package info from
...@@ -64,11 +66,19 @@ public final class WebLayer { ...@@ -64,11 +66,19 @@ public final class WebLayer {
delegate.addWebViewAssetPath(application); delegate.addWebViewAssetPath(application);
Context remoteContext = createRemoteContext(application); Context remoteContext = createRemoteContext(application);
Class webLayerClass = remoteContext.getClassLoader().loadClass(
"org.chromium.weblayer_private.WebLayerImpl");
// Check version before doing anything else on the implementation side.
if (!(boolean) webLayerClass.getMethod("checkVersion", Integer.TYPE)
.invoke(null, WebLayerVersion.sVersionNumber)) {
throw new UnsupportedVersionException(WebLayerVersion.sVersionNumber);
}
return IWebLayer.Stub.asInterface( return IWebLayer.Stub.asInterface(
(IBinder) remoteContext.getClassLoader() (IBinder) webLayerClass.getMethod("create").invoke(null));
.loadClass("org.chromium.weblayer_private.WebLayerImpl") } catch (UnsupportedVersionException e) {
.getMethod("create") throw e;
.invoke(null));
} catch (Exception e) { } catch (Exception e) {
throw new APICallException(e); throw new APICallException(e);
} }
...@@ -82,7 +92,8 @@ public final class WebLayer { ...@@ -82,7 +92,8 @@ public final class WebLayer {
* @return a ListenableFuture whose value will contain the WebLayer once initialization * @return a ListenableFuture whose value will contain the WebLayer once initialization
* completes * completes
*/ */
public static ListenableFuture<WebLayer> create(Application application) { public static ListenableFuture<WebLayer> create(Application application)
throws UnsupportedVersionException {
if (sFuture == null) { if (sFuture == null) {
IWebLayer iWebLayer = connectToWebLayerImplementation(application); IWebLayer iWebLayer = connectToWebLayerImplementation(application);
sFuture = new WebLayerLoadFuture(iWebLayer, application); sFuture = new WebLayerLoadFuture(iWebLayer, application);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment