Add an API for retrieving information about the current WebView package.
Now that WebView can be loaded from one out of a set of packages we
provide an API for fetching information about this package.
Such API is especially useful for debugging crashes.
Bug: 30597460
Change-Id: I13dd746f7efcf2917b517053010b73ea35241325
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 43cdf59..6d97796 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.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 @@
@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 3a93b46..b69a8c1 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 @@
return mSystemInterface.getWebViewPackages();
}
- String getCurrentWebViewPackageName() {
- return mWebViewUpdater.getCurrentWebViewPackageName();
+ PackageInfo getCurrentWebViewPackage() {
+ return mWebViewUpdater.getCurrentWebViewPackage();
}
void enableFallbackLogic(boolean enable) {
@@ -316,6 +316,7 @@
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 @@
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 @@
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 @@
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 7f171fb..0f898e5 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 @@
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 @@
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 @@
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);
+ }
}