From f8e48ec17a576cfd005cf3f7c4658add2804dfb8 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Fri, 22 Jan 2021 11:25:17 +0800 Subject: [PATCH] Fixes a crash when the instant app is launching The provider of an instant app is allowed to declare itself defined in other split apk using the `splitName` attribute. Platform did not aware this attribut and try to install a provider which is defined in an non-installed split apk. The ClassNotFoundException is thrown during the app is launching. Bug: 178053703 Test: atest SplitTests Change-Id: I3de73487fc8fdb2b4735882ad4c3e5481274da0b --- .../server/am/ContentProviderHelper.java | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java index aabe6ccf6a378..89ed42377b071 100644 --- a/services/core/java/com/android/server/am/ContentProviderHelper.java +++ b/services/core/java/com/android/server/am/ContentProviderHelper.java @@ -1090,6 +1090,17 @@ public class ContentProviderHelper { i--; continue; } + final boolean isInstantApp = cpi.applicationInfo.isInstantApp(); + final boolean splitInstalled = cpi.splitName == null || ArrayUtils.contains( + cpi.applicationInfo.splitNames, cpi.splitName); + if (isInstantApp && !splitInstalled) { + // For instant app, allow provider that is defined in the provided split apk. + // Skipping it if the split apk is not installed. + providers.remove(i); + numProviders--; + i--; + continue; + } ComponentName comp = new ComponentName(cpi.packageName, cpi.name); ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, app.userId); @@ -1112,7 +1123,7 @@ public class ContentProviderHelper { mService.notifyPackageUse(cpi.applicationInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER); } - return providers; + return providers.isEmpty() ? null : providers; } private final class DevelopmentSettingsObserver extends ContentObserver { @@ -1217,7 +1228,12 @@ public class ContentProviderHelper { final boolean userMatch = !mService.isSingleton( pi.processName, pi.applicationInfo, pi.name, pi.flags) || app.userId == UserHandle.USER_SYSTEM; - if (processMatch && userMatch) { + final boolean isInstantApp = pi.applicationInfo.isInstantApp(); + final boolean splitInstalled = pi.splitName == null + || ArrayUtils.contains(pi.applicationInfo.splitNames, + pi.splitName); + if (processMatch && userMatch + && (!isInstantApp || splitInstalled)) { Log.v(TAG, "Installing " + pi); app.thread.scheduleInstallProvider(pi); } else {