Support using uninstalled WebView packages as WebView implementation.

A package can be uninstalled for the system user but still be installed
on the device. Currently, we do not use such a package as WebView
implementation which means we fall back to using the fallback WebView
package.
However, if the fallback package is not valid (because it needs to be
updated first) loading WebView will fail.

With this change we fetch allow the fetching of information from
packages that are uninstalled for the system user so that we can still
load WebView when the only valid WebView provider is uninstalled for the
system user.

Also listen to package additions/changes/removals for all users -
otherwise we won't notice when a package becomes replaced if it was
already uninstalled for the system user.

Bug: 29321185
Change-Id: Ia23c4493844877aea1b4eab7e666fd37540c4f97
diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
index 9b971e0..846169c 100644
--- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java
+++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java
@@ -63,6 +63,7 @@
         mWebViewUpdatedReceiver = new BroadcastReceiver() {
                 @Override
                 public void onReceive(Context context, Intent intent) {
+                    int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                     switch (intent.getAction()) {
                         case Intent.ACTION_PACKAGE_REMOVED:
                             // When a package is replaced we will receive two intents, one
@@ -73,24 +74,22 @@
                             // run the update-logic twice.
                             if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) return;
                             mImpl.packageStateChanged(packageNameFromIntent(intent),
-                                    PACKAGE_REMOVED);
+                                    PACKAGE_REMOVED, userId);
                             break;
                         case Intent.ACTION_PACKAGE_CHANGED:
                             // Ensure that we only heed PACKAGE_CHANGED intents if they change an
                             // entire package, not just a component
                             if (entirePackageChanged(intent)) {
                                 mImpl.packageStateChanged(packageNameFromIntent(intent),
-                                        PACKAGE_CHANGED);
+                                        PACKAGE_CHANGED, userId);
                             }
                             break;
                         case Intent.ACTION_PACKAGE_ADDED:
                             mImpl.packageStateChanged(packageNameFromIntent(intent),
                                     (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)
-                                     ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED));
+                                     ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED), userId);
                             break;
                         case Intent.ACTION_USER_ADDED:
-                            int userId =
-                                intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                             mImpl.handleNewUser(userId);
                             break;
                     }
@@ -105,11 +104,14 @@
         for (WebViewProviderInfo provider : mImpl.getWebViewPackages()) {
             filter.addDataSchemeSpecificPart(provider.packageName, PatternMatcher.PATTERN_LITERAL);
         }
-        getContext().registerReceiver(mWebViewUpdatedReceiver, filter);
+
+        getContext().registerReceiverAsUser(mWebViewUpdatedReceiver, UserHandle.ALL, filter,
+                null /* broadcast permission */, null /* handler */);
 
         IntentFilter userAddedFilter = new IntentFilter();
         userAddedFilter.addAction(Intent.ACTION_USER_ADDED);
-        getContext().registerReceiver(mWebViewUpdatedReceiver, userAddedFilter);
+        getContext().registerReceiverAsUser(mWebViewUpdatedReceiver, UserHandle.ALL,
+                userAddedFilter, null /* broadcast permission */, null /* handler */);
 
         publishBinderService("webviewupdate", new BinderService(), true /*allowIsolated*/);
     }