From 2dd3ad06d6413928448f0735c937a414018520ba Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Fri, 21 Jul 2017 10:49:58 -0700 Subject: [PATCH] dynamically install all missing splits In O, we allowed Instant Apps to dynamically install missing splits. We removed that limit and allow any application [ie. full applications] to dynamically install missing splits. This functionality only works on activities. Missing splits will not be dynamically installed when referencing other components such as receivers, providers or services. Change-Id: Iab1db1ebc80f517d711ae113e68d7adcc2a39d9f Fixes: 63112542 Test: Manual. Test: Install a app that references a split that isn't installed Test: Invoke the missing split and see that the installer is launched --- .../server/pm/PackageManagerService.java | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 98b6949a85e31..e7fec64096751 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -7209,34 +7209,31 @@ public class PackageManagerService extends IPackageManager.Stub String ephemeralPkgName) { for (int i = resolveInfos.size() - 1; i >= 0; i--) { final ResolveInfo info = resolveInfos.get(i); - final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp(); // TODO: When adding on-demand split support for non-instant apps, remove this check // and always apply post filtering // allow activities that are defined in the provided package - if (isEphemeralApp) { - if (info.activityInfo.splitName != null - && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames, - info.activityInfo.splitName)) { - // requested activity is defined in a split that hasn't been installed yet. - // add the installer to the resolve list - if (DEBUG_EPHEMERAL) { - Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list"); - } - final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo); - installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo( - info.activityInfo.packageName, info.activityInfo.splitName, - info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/); - // make sure this resolver is the default - installerInfo.isDefault = true; - installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART - | IntentFilter.MATCH_ADJUSTMENT_NORMAL; - // add a non-generic filter - installerInfo.filter = new IntentFilter(); - // load resources from the correct package - installerInfo.resolvePackageName = info.getComponentInfo().packageName; - resolveInfos.set(i, installerInfo); - continue; + if (info.activityInfo.splitName != null + && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames, + info.activityInfo.splitName)) { + // requested activity is defined in a split that hasn't been installed yet. + // add the installer to the resolve list + if (DEBUG_INSTALL) { + Slog.v(TAG, "Adding installer to the ResolveInfo list"); } + final ResolveInfo installerInfo = new ResolveInfo(mInstantAppInstallerInfo); + installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo( + info.activityInfo.packageName, info.activityInfo.splitName, + info.activityInfo.applicationInfo.versionCode, null /*failureIntent*/); + // make sure this resolver is the default + installerInfo.isDefault = true; + installerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART + | IntentFilter.MATCH_ADJUSTMENT_NORMAL; + // add a non-generic filter + installerInfo.filter = new IntentFilter(); + // load resources from the correct package + installerInfo.resolvePackageName = info.getComponentInfo().packageName; + resolveInfos.set(i, installerInfo); + continue; } // caller is a full app, don't need to apply any other filtering if (ephemeralPkgName == null) { @@ -7246,6 +7243,7 @@ public class PackageManagerService extends IPackageManager.Stub continue; } // allow activities that have been explicitly exposed to ephemeral apps + final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp(); if (!isEphemeralApp && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) { continue;