Loading core/java/android/webkit/UserPackage.java +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading core/java/android/webkit/WebViewFactory.java +8 −22 Original line number Diff line number Diff line Loading @@ -147,16 +147,8 @@ public final class WebViewFactory { */ 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); } } /** Loading Loading @@ -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()); } if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); return sProviderInstance; } catch (Exception e) { Loading Loading @@ -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) { Loading services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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 */); } } Loading
core/java/android/webkit/UserPackage.java +10 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading
core/java/android/webkit/WebViewFactory.java +8 −22 Original line number Diff line number Diff line Loading @@ -147,16 +147,8 @@ public final class WebViewFactory { */ 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); } } /** Loading Loading @@ -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()); } if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); return sProviderInstance; } catch (Exception e) { Loading Loading @@ -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) { Loading
services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +4 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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 */); } }