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
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user