diff options
| author | 2016-10-17 18:06:43 +0000 | |
|---|---|---|
| committer | 2016-10-17 18:06:48 +0000 | |
| commit | 905e807ee255e4e6f59d04ef0fba9a7cf4eabb20 (patch) | |
| tree | b7029d0e12e19289790562cb9a4a301fb56c216d | |
| parent | cf6782c9409f98404302eba22c891072291e73b3 (diff) | |
| parent | bf683e07c350ed7cd2c8e877b447e1dd41863a94 (diff) | |
Merge "Add an API for retrieving information about the current WebView package."
| -rw-r--r-- | api/current.txt | 1 | ||||
| -rw-r--r-- | api/system-current.txt | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 1 | ||||
| -rw-r--r-- | core/java/android/webkit/IWebViewUpdateService.aidl | 5 | ||||
| -rw-r--r-- | core/java/android/webkit/WebView.java | 22 | ||||
| -rw-r--r-- | core/java/android/webkit/WebViewFactory.java | 15 | ||||
| -rw-r--r-- | services/core/java/com/android/server/webkit/WebViewUpdateService.java | 9 | ||||
| -rw-r--r-- | services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java | 13 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java | 66 |
9 files changed, 118 insertions, 15 deletions
diff --git a/api/current.txt b/api/current.txt index 469d868f6a25..a051efdc68a5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -45845,6 +45845,7 @@ package android.webkit { method public deprecated void freeMemory(); method public android.net.http.SslCertificate getCertificate(); method public int getContentHeight(); + method public static android.content.pm.PackageInfo getCurrentWebViewPackage(); method public android.graphics.Bitmap getFavicon(); method public android.webkit.WebView.HitTestResult getHitTestResult(); method public deprecated java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index 3fcfd009d8a6..ae0095dbef04 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -49122,6 +49122,7 @@ package android.webkit { method public deprecated void freeMemory(); method public android.net.http.SslCertificate getCertificate(); method public int getContentHeight(); + method public static android.content.pm.PackageInfo getCurrentWebViewPackage(); method public android.graphics.Bitmap getFavicon(); method public android.webkit.WebView.HitTestResult getHitTestResult(); method public deprecated java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String); diff --git a/api/test-current.txt b/api/test-current.txt index a6ddf35c9afe..4a65a7f29db8 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -46083,6 +46083,7 @@ package android.webkit { method public deprecated void freeMemory(); method public android.net.http.SslCertificate getCertificate(); method public int getContentHeight(); + method public static android.content.pm.PackageInfo getCurrentWebViewPackage(); method public android.graphics.Bitmap getFavicon(); method public android.webkit.WebView.HitTestResult getHitTestResult(); method public deprecated java.lang.String[] getHttpAuthUsernamePassword(java.lang.String, java.lang.String); diff --git a/core/java/android/webkit/IWebViewUpdateService.aidl b/core/java/android/webkit/IWebViewUpdateService.aidl index 9434f0ccac4e..894f080af460 100644 --- a/core/java/android/webkit/IWebViewUpdateService.aidl +++ b/core/java/android/webkit/IWebViewUpdateService.aidl @@ -64,6 +64,11 @@ interface IWebViewUpdateService { String getCurrentWebViewPackageName(); /** + * Used by public API for debugging purposes. + */ + PackageInfo getCurrentWebViewPackage(); + + /** * Used by Settings to determine whether a certain package can be enabled/disabled by the user - * the package should not be modifiable in this way if it is a fallback package. */ diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 8c725cffd6e2..939f45fc45e2 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -21,6 +21,7 @@ import android.annotation.SystemApi; import android.annotation.Widget; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -36,6 +37,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.StrictMode; +import android.os.RemoteException; import android.print.PrintDocumentAdapter; import android.security.KeyChain; import android.util.AttributeSet; @@ -2674,6 +2676,26 @@ public class WebView extends AbsoluteLayout } /** + * If WebView has already been loaded into the current process this method will return the + * package that was used to load it. Otherwise, the package that would be used if the WebView + * was loaded right now will be returned; this does not cause WebView to be loaded, so this + * information may become outdated at any time. + * @return the current WebView package, or null if there is none. + */ + public static PackageInfo getCurrentWebViewPackage() { + PackageInfo webviewPackage = WebViewFactory.getLoadedPackageInfo(); + if (webviewPackage != null) { + return webviewPackage; + } + + try { + return WebViewFactory.getUpdateService().getCurrentWebViewPackage(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Receive the result from a previous call to {@link #startActivityForResult(Intent, int)}. * * @param requestCode The integer request code originally supplied to diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 4bfc71878914..884a86c0ad2e 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -135,7 +135,9 @@ public final class WebViewFactory { } public static PackageInfo getLoadedPackageInfo() { - return sPackageInfo; + synchronized (sProviderLock) { + return sPackageInfo; + } } /** @@ -170,9 +172,8 @@ public final class WebViewFactory { Log.e(LOGTAG, "Couldn't find package " + packageName); return LIBLOAD_WRONG_PACKAGE_NAME; } - sPackageInfo = packageInfo; - int loadNativeRet = loadNativeLibrary(clazzLoader); + int loadNativeRet = loadNativeLibrary(clazzLoader, packageInfo); // If we failed waiting for relro we want to return that fact even if we successfully load // the relro file. if (loadNativeRet == LIBLOAD_SUCCESS) return response.status; @@ -358,7 +359,7 @@ public final class WebViewFactory { ClassLoader clazzLoader = webViewContext.getClassLoader(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); - loadNativeLibrary(clazzLoader); + loadNativeLibrary(clazzLoader, sPackageInfo); Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); @@ -637,14 +638,14 @@ public final class WebViewFactory { } } - // Assumes that we have waited for relro creation and set sPackageInfo - private static int loadNativeLibrary(ClassLoader clazzLoader) { + // Assumes that we have waited for relro creation + private static int loadNativeLibrary(ClassLoader clazzLoader, PackageInfo packageInfo) { if (!sAddressSpaceReserved) { Log.e(LOGTAG, "can't load with relro file; address space not reserved"); return LIBLOAD_ADDRESS_SPACE_NOT_RESERVED; } - String[] args = getWebViewNativeLibraryPaths(sPackageInfo); + String[] args = getWebViewNativeLibraryPaths(packageInfo); int result = nativeLoadWithRelroFile(args[0] /* path32 */, args[1] /* path64 */, CHROMIUM_WEBVIEW_NATIVE_RELRO_32, diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index 43cdf5978068..6d97796d3d3e 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -20,6 +20,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Binder; import android.os.PatternMatcher; @@ -224,7 +225,13 @@ public class WebViewUpdateService extends SystemService { @Override // Binder call public String getCurrentWebViewPackageName() { - return WebViewUpdateService.this.mImpl.getCurrentWebViewPackageName(); + PackageInfo pi = WebViewUpdateService.this.mImpl.getCurrentWebViewPackage(); + return pi == null ? null : pi.packageName; + } + + @Override // Binder call + public PackageInfo getCurrentWebViewPackage() { + return WebViewUpdateService.this.mImpl.getCurrentWebViewPackage(); } @Override // Binder call diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java index 3a93b4664f3e..b69a8c1baad4 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java @@ -145,8 +145,8 @@ public class WebViewUpdateServiceImpl { return mSystemInterface.getWebViewPackages(); } - String getCurrentWebViewPackageName() { - return mWebViewUpdater.getCurrentWebViewPackageName(); + PackageInfo getCurrentWebViewPackage() { + return mWebViewUpdater.getCurrentWebViewPackage(); } void enableFallbackLogic(boolean enable) { @@ -316,6 +316,7 @@ public class WebViewUpdateServiceImpl { onWebViewProviderChanged(newPackage); } } catch (WebViewPackageMissingException e) { + mCurrentWebViewPackage = null; Slog.e(TAG, "Could not find valid WebView package to create " + "relro with " + e); } @@ -371,6 +372,7 @@ public class WebViewUpdateServiceImpl { providerChanged = (oldPackage == null) || !newPackage.packageName.equals(oldPackage.packageName); } catch (WebViewPackageMissingException e) { + mCurrentWebViewPackage = null; Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView " + "package " + e); // If we don't perform the user change but don't have an installed WebView @@ -548,11 +550,9 @@ public class WebViewUpdateServiceImpl { return new WebViewProviderResponse(webViewPackage, webViewStatus); } - public String getCurrentWebViewPackageName() { + public PackageInfo getCurrentWebViewPackage() { synchronized(mLock) { - if (mCurrentWebViewPackage == null) - return null; - return mCurrentWebViewPackage.packageName; + return mCurrentWebViewPackage; } } @@ -579,6 +579,7 @@ public class WebViewUpdateServiceImpl { PackageInfo newPackage = findPreferredWebViewPackage(); onWebViewProviderChanged(newPackage); } catch (WebViewPackageMissingException e) { + mCurrentWebViewPackage = null; // If we can't find any valid WebView package we are now in a state where // mAnyWebViewInstalled is false, so loading WebView will be blocked and we // should simply wait until we receive an intent declaring a new package was 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 7f171fbd9390..0f898e594548 100644 --- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java @@ -303,6 +303,31 @@ public class WebViewUpdateServiceTest extends AndroidTestCase { WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider(); assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status); + assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage()); + + // Now install a package + String singlePackage = "singlePackage"; + packages = new WebViewProviderInfo[]{ + new WebViewProviderInfo(singlePackage, "", true, false, null)}; + setupWithPackages(packages); + setEnabledAndValidPackageInfos(packages); + + mWebViewUpdateServiceImpl.packageStateChanged(singlePackage, + WebViewUpdateService.PACKAGE_ADDED, 0); + + checkPreparationPhasesForPackage(singlePackage, 1 /* number of finished preparations */); + assertEquals(singlePackage, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName); + + // Remove the package again + mTestSystemImpl.removePackageInfo(singlePackage); + mWebViewUpdateServiceImpl.packageStateChanged(singlePackage, + WebViewUpdateService.PACKAGE_ADDED, 0); + + // Package removed - ensure our interface states that there is no package + response = mWebViewUpdateServiceImpl.waitForAndGetProvider(); + assertEquals(WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES, response.status); + assertEquals(null, mWebViewUpdateServiceImpl.getCurrentWebViewPackage()); } public void testFailListingInvalidWebviewPackage() { @@ -395,7 +420,8 @@ public class WebViewUpdateServiceTest extends AndroidTestCase { Mockito.verify(mTestSystemImpl).onWebViewProviderChanged( Mockito.argThat(new IsPackageInfoWithName(firstPackage))); - assertEquals(firstPackage, mWebViewUpdateServiceImpl.getCurrentWebViewPackageName()); + assertEquals(firstPackage, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName); new Thread(new Runnable() { @Override @@ -1243,4 +1269,42 @@ public class WebViewUpdateServiceTest extends AndroidTestCase { checkPreparationPhasesForPackage(primaryPackage, 3 /* third preparation phase */); } + + public void testGetCurrentWebViewPackage() { + PackageInfo firstPackage = createPackageInfo("first", true /* enabled */, + true /* valid */, true /* installed */); + firstPackage.versionCode = 100; + firstPackage.versionName = "first package version"; + WebViewProviderInfo[] packages = new WebViewProviderInfo[] { + new WebViewProviderInfo(firstPackage.packageName, "", true, false, null)}; + setupWithPackages(packages, true); + mTestSystemImpl.setPackageInfo(firstPackage); + + mWebViewUpdateServiceImpl.prepareWebViewInSystemServer(); + + Mockito.verify(mTestSystemImpl).onWebViewProviderChanged( + Mockito.argThat(new IsPackageInfoWithName(firstPackage.packageName))); + + mWebViewUpdateServiceImpl.notifyRelroCreationCompleted(); + + // Ensure the API is correct before running waitForAndGetProvider + assertEquals(firstPackage.packageName, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName); + assertEquals(firstPackage.versionCode, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionCode); + assertEquals(firstPackage.versionName, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName); + + WebViewProviderResponse response = mWebViewUpdateServiceImpl.waitForAndGetProvider(); + assertEquals(WebViewFactory.LIBLOAD_SUCCESS, response.status); + assertEquals(firstPackage.packageName, response.packageInfo.packageName); + + // Ensure the API is still correct after running waitForAndGetProvider + assertEquals(firstPackage.packageName, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().packageName); + assertEquals(firstPackage.versionCode, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionCode); + assertEquals(firstPackage.versionName, + mWebViewUpdateServiceImpl.getCurrentWebViewPackage().versionName); + } } |