summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Gustav Sennton <gsennton@google.com> 2017-01-30 18:08:01 +0000
committer Gustav Sennton <gsennton@google.com> 2017-02-01 13:59:26 +0000
commit564c2fd5db707dbe3e10df3e69780c0ab6ce7a51 (patch)
treec5fa4218903f21e82af56dedb5ce49cc568469f6
parent9deb6b5a3a1ee9ed0eaa646e918ac131fb50b19c (diff)
Make sure we cannot use packages targeting pre-O as WebView packages.
Using a WebView package targeting a release before O as WebView provider on O will cause crashes (because of incompatibility issues), this CL makes us interpret a package targeting a pre-O release as being invalid on O. Also remove the code that lets us fall back to loading the old WebViewChromiumFactoryProvider (pre-O) class. Bug: 34773740 Bug: 34180497 Test: Ensure WebView provider with targetSdkVersion="O" shows up in the WebView Implementation Dev Setting, ensure targetSdkVersion=25 doesn't show up. Test: Add WVUS unit test to ensure a packages with targetSdkVersion < 26 are considered invalid, and > 26 are valid. Run WVUS unit tests. Change-Id: I4d80d46019e2522bc3fc6068712d28eedb31fcce
-rw-r--r--core/java/android/webkit/UserPackage.java10
-rw-r--r--core/java/android/webkit/WebViewFactory.java30
-rw-r--r--services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java42
4 files changed, 64 insertions, 22 deletions
diff --git a/core/java/android/webkit/UserPackage.java b/core/java/android/webkit/UserPackage.java
index 404bcf453aaf..f53b5d6a7cd7 100644
--- a/core/java/android/webkit/UserPackage.java
+++ b/core/java/android/webkit/UserPackage.java
@@ -20,6 +20,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
+import android.os.Build;
import android.os.UserManager;
import java.util.ArrayList;
@@ -77,6 +78,15 @@ public class UserPackage {
& ApplicationInfo.PRIVATE_FLAG_HIDDEN) == 0));
}
+ /**
+ * Returns whether the package represented by {@param packageInfo} targets a sdk version
+ * supported by the current framework version.
+ */
+ public static boolean hasCorrectTargetSdkVersion(PackageInfo packageInfo) {
+ // TODO(gsennton) use Build.VERSION_CODES.O when that has been updated.
+ return packageInfo.applicationInfo.targetSdkVersion > Build.VERSION_CODES.N_MR1;
+ }
+
public UserInfo getUserInfo() {
return mUserInfo;
}
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index d7a49e46a236..0906d1a1e034 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -145,18 +145,10 @@ public final class WebViewFactory {
/**
* @hide
*/
- public static Class<WebViewFactoryProvider> getWebViewProviderClass( ClassLoader clazzLoader)
- throws ClassNotFoundException{
- try {
- return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
- true, clazzLoader);
- } catch (ClassNotFoundException e) {
- // TODO: This loads the provider which is not built for O, should be removed
- // before the release.
- return (Class<WebViewFactoryProvider>) Class.forName(
- "com.android.webview.chromium.WebViewChromiumFactoryProvider",
- true, clazzLoader);
- }
+ public static Class<WebViewFactoryProvider> getWebViewProviderClass(ClassLoader clazzLoader)
+ throws ClassNotFoundException {
+ return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY,
+ true, clazzLoader);
}
/**
@@ -225,15 +217,10 @@ public final class WebViewFactory {
}
}
- Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()");
+ Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactoryProvider invocation");
try {
- if (staticFactory != null) {
- sProviderInstance = (WebViewFactoryProvider)
- staticFactory.invoke(null, new WebViewDelegate());
- } else {
- sProviderInstance = providerClass.getConstructor(WebViewDelegate.class)
- .newInstance(new WebViewDelegate());
- }
+ sProviderInstance = (WebViewFactoryProvider)
+ staticFactory.invoke(null, new WebViewDelegate());
if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance);
return sProviderInstance;
} catch (Exception e) {
@@ -384,8 +371,7 @@ public final class WebViewFactory {
Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()");
try {
return getWebViewProviderClass(clazzLoader);
- }
- finally {
+ } finally {
Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
}
} catch (ClassNotFoundException e) {
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
index fedd55a9b5b6..83e77ec3f9ae 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java
@@ -630,6 +630,10 @@ public class WebViewUpdateServiceImpl {
*/
public boolean isValidProvider(WebViewProviderInfo configInfo,
PackageInfo packageInfo) {
+ // Ensure the provider targets this framework release (or a later one).
+ if (!UserPackage.hasCorrectTargetSdkVersion(packageInfo)) {
+ return false;
+ }
if (!versionCodeGE(packageInfo.versionCode, getMinimumVersionCode())
&& !mSystemInterface.systemIsDebuggable()) {
// Webview providers may be downgraded arbitrarily low, prevent that by enforcing
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 4c0f0424cf18..e4b74eb07264 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -16,6 +16,7 @@
package com.android.server.webkit;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -24,6 +25,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.Signature;
+import android.os.Build;
import android.os.Bundle;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
@@ -174,6 +176,8 @@ public class WebViewUpdateServiceTest {
// no flag means invalid
p.applicationInfo.metaData.putString(WEBVIEW_LIBRARY_FLAG, "blah");
}
+ // Default to this package being valid in terms of targetSdkVersion.
+ p.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
return p;
}
@@ -1614,4 +1618,42 @@ public class WebViewUpdateServiceTest {
checkPreparationPhasesForPackage(primaryPackage, 3);
assertTrue(mWebViewUpdateServiceImpl.isMultiProcessEnabled());
}
+
+ /**
+ * Ensure that packages with a targetSdkVersion targeting the current platform are valid, and
+ * that packages targeting an older version are not valid.
+ */
+ @Test
+ public void testTargetSdkVersionValidity() {
+ PackageInfo newSdkPackage = createPackageInfo("newTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ newSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ PackageInfo currentSdkPackage = createPackageInfo("currentTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ currentSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1+1;
+ PackageInfo oldSdkPackage = createPackageInfo("oldTargetSdkPackage",
+ true /* enabled */, true /* valid */, true /* installed */);
+ oldSdkPackage.applicationInfo.targetSdkVersion = Build.VERSION_CODES.N_MR1;
+
+ WebViewProviderInfo newSdkProviderInfo =
+ new WebViewProviderInfo(newSdkPackage.packageName, "", true, false, null);
+ WebViewProviderInfo currentSdkProviderInfo =
+ new WebViewProviderInfo(currentSdkPackage.packageName, "", true, false, null);
+ WebViewProviderInfo[] packages = new WebViewProviderInfo[] {
+ new WebViewProviderInfo(oldSdkPackage.packageName, "", true, false, null),
+ currentSdkProviderInfo, newSdkProviderInfo};
+ setupWithPackages(packages, true);
+;
+ mTestSystemImpl.setPackageInfo(newSdkPackage);
+ mTestSystemImpl.setPackageInfo(currentSdkPackage);
+ mTestSystemImpl.setPackageInfo(oldSdkPackage);
+
+ assertArrayEquals(new WebViewProviderInfo[]{currentSdkProviderInfo, newSdkProviderInfo},
+ mWebViewUpdateServiceImpl.getValidWebViewPackages());
+
+ runWebViewBootPreparationOnMainSync();
+
+ checkPreparationPhasesForPackage(currentSdkPackage.packageName,
+ 1 /* first preparation phase */);
+ }
}