diff options
34 files changed, 551 insertions, 374 deletions
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index b336472666bd..7965fc342514 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -554,8 +554,12 @@ public final class Pm { sessionParams.abiOverride = checkAbiArgument(nextOptionData()); break; case "--ephemeral": + case "--instant": sessionParams.setInstallAsInstantApp(true /*isInstantApp*/); break; + case "--full": + sessionParams.setInstallAsInstantApp(false /*isInstantApp*/); + break; case "--user": params.userId = UserHandle.parseUserArg(nextOptionData()); break; diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 333e412e1c33..165229912547 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1687,7 +1687,7 @@ public class ApplicationPackageManager extends PackageManager { public int installExistingPackageAsUser(String packageName, int userId) throws NameNotFoundException { try { - int res = mPM.installExistingPackageAsUser(packageName, userId, + int res = mPM.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); if (res == INSTALL_FAILED_INVALID_URI) { throw new NameNotFoundException("Package " + packageName + " doesn't exist"); diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index e6cae6932402..56609eb57b0d 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -284,8 +284,6 @@ public class IntentFilter implements Parcelable { /** Whether or not the intent filter is visible to ephemeral apps. */ private boolean mVisibleToEphemeral; - /** Whether or not the intent filter is part of an ephemeral app. */ - private boolean mEphemeral; // These functions are the start of more optimized code for managing // the string sets... not yet implemented. @@ -656,19 +654,10 @@ public class IntentFilter implements Parcelable { mVisibleToEphemeral = visibleToEmphemeral; } /** @hide */ - public boolean isVisibleToEphemeral() { + public boolean isVisibleToInstantApp() { return mVisibleToEphemeral; } - /** @hide */ - public void setEphemeral(boolean ephemeral) { - mEphemeral = ephemeral; - } - /** @hide */ - public boolean isEphemeral() { - return mEphemeral; - } - /** * Add a new Intent action to match against. If any actions are included * in the filter, then an Intent's action must be one of those values for diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index 1fa4181cc2f8..9737b11a0133 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -498,11 +498,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public static final int PRIVATE_FLAG_DIRECT_BOOT_AWARE = 1 << 6; /** - * Value for {@link #flags}: {@code true} if the application is blocked via restrictions - * and for most purposes is considered as not installed. - * {@hide} + * Value for {@link #privateFlags}: {@code true} if the application is installed + * as instant app. + * + * @hide */ - public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 7; + public static final int PRIVATE_FLAG_INSTANT = 1 << 7; /** * When set, at least one component inside this application is direct boot @@ -681,7 +682,21 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * * {@hide} */ - public String seinfo = "default"; + public String seInfo = "default"; + + /** + * The seinfo tag generated per-user. This value may change based upon the + * user's configuration. For example, when an instant app is installed for + * a user. It is an error if this field is ever {@code null} when trying to + * start a new process. + * <p>NOTE: We need to separate this out because we modify per-user values + * multiple times. This needs to be refactored since we're performing more + * work than necessary and these values should only be set once. When that + * happens, we can merge the per-user value with the seInfo state above. + * + * {@hide} + */ + public String seInfoUser; /** * Paths to all shared libraries this application is linked against. This @@ -1009,8 +1024,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { if (resourceDirs != null) { pw.println(prefix + "resourceDirs=" + Arrays.toString(resourceDirs)); } - if ((flags&DUMP_FLAG_DETAILS) != 0 && seinfo != null) { - pw.println(prefix + "seinfo=" + seinfo); + if ((flags&DUMP_FLAG_DETAILS) != 0 && seInfo != null) { + pw.println(prefix + "seinfo=" + seInfo); + pw.println(prefix + "seinfoUser=" + seInfoUser); } pw.println(prefix + "dataDir=" + dataDir); if ((flags&DUMP_FLAG_DETAILS) != 0) { @@ -1120,7 +1136,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { primaryCpuAbi = orig.primaryCpuAbi; secondaryCpuAbi = orig.secondaryCpuAbi; resourceDirs = orig.resourceDirs; - seinfo = orig.seinfo; + seInfo = orig.seInfo; + seInfoUser = orig.seInfoUser; sharedLibraryFiles = orig.sharedLibraryFiles; dataDir = orig.dataDir; deviceEncryptedDataDir = deviceProtectedDataDir = orig.deviceProtectedDataDir; @@ -1181,7 +1198,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(primaryCpuAbi); dest.writeString(secondaryCpuAbi); dest.writeStringArray(resourceDirs); - dest.writeString(seinfo); + dest.writeString(seInfo); + dest.writeString(seInfoUser); dest.writeStringArray(sharedLibraryFiles); dest.writeString(dataDir); dest.writeString(deviceProtectedDataDir); @@ -1242,7 +1260,8 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { primaryCpuAbi = source.readString(); secondaryCpuAbi = source.readString(); resourceDirs = source.readStringArray(); - seinfo = source.readString(); + seInfo = source.readString(); + seInfoUser = source.readString(); sharedLibraryFiles = source.readStringArray(); dataDir = source.readString(); deviceEncryptedDataDir = deviceProtectedDataDir = source.readString(); @@ -1330,7 +1349,6 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { } else { dataDir = credentialProtectedDataDir; } - // TODO: modify per-user ephemerality } /** @@ -1415,7 +1433,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { * @hide */ public boolean isInstantApp() { - return (privateFlags & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0; + return (privateFlags & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0; } /** diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 9d36a730ac09..ffb777db579c 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -553,7 +553,8 @@ interface IPackageManager { boolean setInstallLocation(int loc); int getInstallLocation(); - int installExistingPackageAsUser(String packageName, int userId, int installReason); + int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason); void verifyPendingInstall(int id, int verificationCode); void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay); diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 4de967c50dcd..278a6d09d9fe 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1096,9 +1096,11 @@ public class PackageInstaller { @SystemApi public void setInstallAsInstantApp(boolean isInstantApp) { if (isInstantApp) { - installFlags |= PackageManager.INSTALL_EPHEMERAL; + installFlags |= PackageManager.INSTALL_INSTANT_APP; + installFlags &= ~PackageManager.INSTALL_FULL_APP; } else { - installFlags &= ~PackageManager.INSTALL_EPHEMERAL; + installFlags &= ~PackageManager.INSTALL_INSTANT_APP; + installFlags |= PackageManager.INSTALL_FULL_APP; } } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 308153dd3538..5733982315d7 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -452,17 +452,17 @@ public abstract class PackageManager { /** * Internal {@link PackageInfo} flag: include components that are part of an - * ephemeral app. By default, ephemeral components are not matched. + * instant app. By default, instant app components are not matched. * @hide */ - public static final int MATCH_EPHEMERAL = 0x00800000; + public static final int MATCH_INSTANT = 0x00800000; /** * Internal {@link PackageInfo} flag: include only components that are exposed to * ephemeral apps. * @hide */ - public static final int MATCH_VISIBLE_TO_EPHEMERAL_ONLY = 0x01000000; + public static final int MATCH_VISIBLE_TO_INSTANT_APP_ONLY = 0x01000000; /** * Internal flag used to indicate that a system component has done their @@ -613,7 +613,7 @@ public abstract class PackageManager { INSTALL_GRANT_RUNTIME_PERMISSIONS, INSTALL_FORCE_VOLUME_UUID, INSTALL_FORCE_PERMISSION_PROMPT, - INSTALL_EPHEMERAL, + INSTALL_INSTANT_APP, INSTALL_DONT_KILL_APP, }) @Retention(RetentionPolicy.SOURCE) @@ -714,7 +714,16 @@ public abstract class PackageManager { * * @hide */ - public static final int INSTALL_EPHEMERAL = 0x00000800; + public static final int INSTALL_INSTANT_APP = 0x00000800; + + /** + * Flag parameter for {@link #installPackage} to indicate that this package is + * to be installed as a heavy weight app. This is fundamentally the opposite of + * {@link #INSTALL_INSTANT_APP}. + * + * @hide + */ + public static final int INSTALL_FULL_APP = 0x00004000; /** * Flag parameter for {@link #installPackage} to indicate that this package contains @@ -1185,12 +1194,12 @@ public abstract class PackageManager { public static final int INSTALL_FAILED_ABORTED = -115; /** - * Installation failed return code: ephemeral app installs are incompatible with some + * Installation failed return code: instant app installs are incompatible with some * other installation flags supplied for the operation; or other circumstances such - * as trying to upgrade a system app via an ephemeral install. + * as trying to upgrade a system app via an instant app install. * @hide */ - public static final int INSTALL_FAILED_EPHEMERAL_INVALID = -116; + public static final int INSTALL_FAILED_INSTANT_APP_INVALID = -116; /** @hide */ @IntDef(flag = true, value = { diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 7a9aaaf40132..98e71a0b4fa2 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -720,6 +720,8 @@ public class PackageParser { public final static int PARSE_COLLECT_CERTIFICATES = 1<<8; public final static int PARSE_TRUSTED_OVERLAY = 1<<9; public final static int PARSE_ENFORCE_CODE = 1<<10; + /** @deprecated remove when fixing b/34761192 */ + @Deprecated public final static int PARSE_IS_EPHEMERAL = 1<<11; public final static int PARSE_FORCE_SDK = 1<<12; @@ -2012,10 +2014,6 @@ public class PackageParser { pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE; } - if ((flags & PARSE_IS_EPHEMERAL) != 0) { - pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL; - } - if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifest_isolatedSplits, false)) { pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING; } @@ -4149,11 +4147,8 @@ public class PackageParser { ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE; } - final boolean hasVisibleToEphemeral = - sa.hasValue(R.styleable.AndroidManifestActivity_visibleToInstantApps); - final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0); - final boolean visibleToEphemeral = isEphemeral - || sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false); + final boolean visibleToEphemeral = + sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false); if (visibleToEphemeral) { a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL; } @@ -4188,8 +4183,6 @@ public class PackageParser { intent, outError)) { return null; } - intent.setEphemeral(isEphemeral); - intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); if (intent.countActions() == 0) { Slog.w(TAG, "No actions in intent filter at " + mArchiveSourcePath + " " @@ -4198,7 +4191,8 @@ public class PackageParser { a.intents.add(intent); } // adjust activity flags when we implicitly expose it via a browsable filter - if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) { + intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); + if (intent.isVisibleToInstantApp()) { a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL; } } else if (!receiver && parser.getName().equals("preferred")) { @@ -4207,8 +4201,6 @@ public class PackageParser { intent, outError)) { return null; } - intent.setEphemeral(isEphemeral); - intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); if (intent.countActions() == 0) { Slog.w(TAG, "No actions in preferred at " + mArchiveSourcePath + " " @@ -4220,7 +4212,8 @@ public class PackageParser { owner.preferredActivityFilters.add(intent); } // adjust activity flags when we implicitly expose it via a browsable filter - if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) { + intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); + if (intent.isVisibleToInstantApp()) { a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL; } } else if (parser.getName().equals("meta-data")) { @@ -4472,9 +4465,8 @@ public class PackageParser { } // TODO add visibleToInstantApps attribute to activity alias - final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0); - final boolean visibleToEphemeral = isEphemeral - || ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0); + final boolean visibleToEphemeral = + ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0); sa.recycle(); @@ -4502,13 +4494,12 @@ public class PackageParser { + mArchiveSourcePath + " " + parser.getPositionDescription()); } else { - intent.setEphemeral(isEphemeral); - intent.setVisibleToEphemeral(visibleToEphemeral - || isWebBrowsableIntent(intent)); + intent.setVisibleToEphemeral( + visibleToEphemeral || isWebBrowsableIntent(intent)); a.intents.add(intent); } // adjust activity flags when we implicitly expose it via a browsable filter - if (intent.isVisibleToEphemeral()) { + if (intent.isVisibleToInstantApp()) { a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL; } } else if (parser.getName().equals("meta-data")) { @@ -4649,11 +4640,8 @@ public class PackageParser { ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE; } - final boolean hasVisibleToEphemeral = - sa.hasValue(R.styleable.AndroidManifestProvider_visibleToInstantApps); - final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0); - final boolean visibleToEphemeral = isEphemeral - || sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false); + final boolean visibleToEphemeral = + sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false); if (visibleToEphemeral) { p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL; } @@ -4681,7 +4669,7 @@ public class PackageParser { p.info.authority = cpname.intern(); if (!parseProviderTags( - res, parser, isEphemeral, hasVisibleToEphemeral, visibleToEphemeral, p, outError)) { + res, parser, visibleToEphemeral, p, outError)) { return null; } @@ -4689,8 +4677,7 @@ public class PackageParser { } private boolean parseProviderTags(Resources res, XmlResourceParser parser, - boolean isEphemeral, boolean hasVisibleToEphemeral, boolean visibleToEphemeral, - Provider outInfo, String[] outError) + boolean visibleToEphemeral, Provider outInfo, String[] outError) throws XmlPullParserException, IOException { int outerDepth = parser.getDepth(); int type; @@ -4707,11 +4694,10 @@ public class PackageParser { intent, outError)) { return false; } - intent.setEphemeral(isEphemeral); - intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); outInfo.intents.add(intent); // adjust provider flags when we implicitly expose it via a browsable filter - if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) { + intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); + if (intent.isVisibleToInstantApp()) { outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL; } @@ -4963,11 +4949,8 @@ public class PackageParser { ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE; } - final boolean hasVisibleToEphemeral = - sa.hasValue(R.styleable.AndroidManifestService_visibleToInstantApps); - final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0); - final boolean visibleToEphemeral = isEphemeral - || sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false); + final boolean visibleToEphemeral = + sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false); if (visibleToEphemeral) { s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL; } @@ -4999,10 +4982,9 @@ public class PackageParser { intent, outError)) { return null; } - intent.setEphemeral(isEphemeral); - intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); // adjust activity flags when we implicitly expose it via a browsable filter - if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) { + intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent)); + if (intent.isVisibleToInstantApp()) { s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL; } s.intents.add(intent); @@ -6482,6 +6464,9 @@ public class PackageParser { if (state.stopped) { return true; } + if (state.instantApp != p.applicationInfo.isInstantApp()) { + return true; + } if ((flags & PackageManager.GET_META_DATA) != 0 && (metaData != null || p.mAppMetaData != null)) { return true; @@ -6517,6 +6502,11 @@ public class PackageParser { } else { ai.flags &= ~ApplicationInfo.FLAG_SUSPENDED; } + if (state.instantApp) { + ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT; + } else { + ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_INSTANT; + } if (state.hidden) { ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN; } else { @@ -6537,6 +6527,7 @@ public class PackageParser { if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) { ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName); } + ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state); } public static ApplicationInfo generateApplicationInfo(Package p, int flags, diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index e19aa99599ef..24f116452f0b 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -43,6 +43,7 @@ public class PackageUserState { public boolean hidden; // Is the app restricted by owner / admin public boolean suspended; public boolean blockUninstall; + public boolean instantApp; public int enabled; public String lastDisableAppCaller; public int domainVerificationStatus; @@ -71,6 +72,7 @@ public class PackageUserState { hidden = o.hidden; suspended = o.suspended; blockUninstall = o.blockUninstall; + instantApp = o.instantApp; enabled = o.enabled; lastDisableAppCaller = o.lastDisableAppCaller; domainVerificationStatus = o.domainVerificationStatus; @@ -188,6 +190,9 @@ public class PackageUserState { if (blockUninstall != oldState.blockUninstall) { return false; } + if (instantApp != oldState.instantApp) { + return false; + } if (enabled != oldState.enabled) { return false; } diff --git a/core/java/android/content/pm/SELinuxUtil.java b/core/java/android/content/pm/SELinuxUtil.java new file mode 100644 index 000000000000..55b5e297e18f --- /dev/null +++ b/core/java/android/content/pm/SELinuxUtil.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm; + +import com.android.internal.util.ArrayUtils; + +/** + * Utility methods that need to be used in application space. + * @hide + */ +public final class SELinuxUtil { + + /** Append to existing seinfo label for instant apps @hide */ + private static final String INSTANT_APP_STR = ":ephemeralapp"; + + /** Append to existing seinfo when modifications are complete @hide */ + public static final String COMPLETE_STR = ":complete"; + + /** @hide */ + public static String assignSeinfoUser(PackageUserState userState) { + String seInfo = ""; + if (userState.instantApp) + seInfo += INSTANT_APP_STR; + seInfo += COMPLETE_STR; + return seInfo; + } + +} diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 9ecc63896e2f..8c184e0ee002 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -4128,20 +4128,20 @@ public final class Settings { } /** - * System settings which can be accessed by ephemeral apps. + * System settings which can be accessed by instant apps. * @hide */ - public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>(); + public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>(); static { - EPHEMERAL_SETTINGS.add(TEXT_AUTO_REPLACE); - EPHEMERAL_SETTINGS.add(TEXT_AUTO_CAPS); - EPHEMERAL_SETTINGS.add(TEXT_AUTO_PUNCTUATE); - EPHEMERAL_SETTINGS.add(TEXT_SHOW_PASSWORD); - EPHEMERAL_SETTINGS.add(DATE_FORMAT); - EPHEMERAL_SETTINGS.add(FONT_SCALE); - EPHEMERAL_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); - EPHEMERAL_SETTINGS.add(TIME_12_24); - EPHEMERAL_SETTINGS.add(SOUND_EFFECTS_ENABLED); + INSTANT_APP_SETTINGS.add(TEXT_AUTO_REPLACE); + INSTANT_APP_SETTINGS.add(TEXT_AUTO_CAPS); + INSTANT_APP_SETTINGS.add(TEXT_AUTO_PUNCTUATE); + INSTANT_APP_SETTINGS.add(TEXT_SHOW_PASSWORD); + INSTANT_APP_SETTINGS.add(DATE_FORMAT); + INSTANT_APP_SETTINGS.add(FONT_SCALE); + INSTANT_APP_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED); + INSTANT_APP_SETTINGS.add(TIME_12_24); + INSTANT_APP_SETTINGS.add(SOUND_EFFECTS_ENABLED); } /** @@ -6996,17 +6996,17 @@ public final class Settings { } /** - * Secure settings which can be accessed by ephemeral apps. + * Secure settings which can be accessed by instant apps. * @hide */ - public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>(); + public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>(); static { - EPHEMERAL_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES); - EPHEMERAL_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD); - EPHEMERAL_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); + INSTANT_APP_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD); + INSTANT_APP_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); - EPHEMERAL_SETTINGS.add(DEFAULT_INPUT_METHOD); - EPHEMERAL_SETTINGS.add(ENABLED_INPUT_METHODS); + INSTANT_APP_SETTINGS.add(DEFAULT_INPUT_METHOD); + INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS); } /** @@ -10144,16 +10144,16 @@ public final class Settings { public static final String CELL_ON = "cell_on"; /** - * Global settings which can be accessed by ephemeral apps. + * Global settings which can be accessed by instant apps. * @hide */ - public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>(); + public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>(); static { - EPHEMERAL_SETTINGS.add(WAIT_FOR_DEBUGGER); - EPHEMERAL_SETTINGS.add(DEVICE_PROVISIONED); - EPHEMERAL_SETTINGS.add(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES); - EPHEMERAL_SETTINGS.add(DEVELOPMENT_FORCE_RTL); - EPHEMERAL_SETTINGS.add(EPHEMERAL_COOKIE_MAX_SIZE_BYTES); + INSTANT_APP_SETTINGS.add(WAIT_FOR_DEBUGGER); + INSTANT_APP_SETTINGS.add(DEVICE_PROVISIONED); + INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES); + INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RTL); + INSTANT_APP_SETTINGS.add(EPHEMERAL_COOKIE_MAX_SIZE_BYTES); } /** diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index eec3cb0be11f..e088717f5fe4 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -534,7 +534,7 @@ public class PackageHelper { final int prefer; final boolean checkBoth; boolean ephemeral = false; - if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { + if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { prefer = RECOMMEND_INSTALL_INTERNAL; ephemeral = true; checkBoth = false; diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java index 4c1119757eba..0fc9a4d6e408 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java +++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java @@ -116,7 +116,7 @@ public class AppRestrictionsHelper { if (info == null || !info.enabled || (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier(), - PackageManager.INSTALL_REASON_UNKNOWN); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); if (DEBUG) { Log.d(TAG, "Installing " + packageName); } diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java index 4df199cbd4bd..8cfec7a520b7 100644 --- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java +++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java @@ -146,7 +146,7 @@ public class AppRestrictionsHelperTest extends BaseTest { mHelper.applyUserAppsStates(mockListener); verify(mIpm, times(1)).installExistingPackageAsUser("app1", testUserId, - PackageManager.INSTALL_REASON_UNKNOWN); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); verify(mIpm, times(1)).setApplicationHiddenSettingAsUser("app2", false, testUserId); verify(mockListener).onDisableUiForPackage("app2"); verify(mPm, times(1)).deletePackageAsUser(eq("app3"), any(IPackageDeleteObserver.class), diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index d5787e6482b5..88fc9cf68a43 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1531,14 +1531,14 @@ public class SettingsProvider extends ContentProvider { } } - private Set<String> getEphemeralAccessibleSettings(int settingsType) { + private Set<String> getInstantAppAccessibleSettings(int settingsType) { switch (settingsType) { case SETTINGS_TYPE_GLOBAL: - return Settings.Global.EPHEMERAL_SETTINGS; + return Settings.Global.INSTANT_APP_SETTINGS; case SETTINGS_TYPE_SECURE: - return Settings.Secure.EPHEMERAL_SETTINGS; + return Settings.Secure.INSTANT_APP_SETTINGS; case SETTINGS_TYPE_SYSTEM: - return Settings.System.EPHEMERAL_SETTINGS; + return Settings.System.INSTANT_APP_SETTINGS; default: throw new IllegalArgumentException("Invalid settings type: " + settingsType); } @@ -1547,7 +1547,7 @@ public class SettingsProvider extends ContentProvider { private List<String> getSettingsNamesLocked(int settingsType, int userId) { ApplicationInfo ai = getCallingApplicationInfoOrThrow(userId); if (ai.isInstantApp()) { - return new ArrayList<String>(getEphemeralAccessibleSettings(settingsType)); + return new ArrayList<String>(getInstantAppAccessibleSettings(settingsType)); } else { return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId); } @@ -1561,7 +1561,7 @@ public class SettingsProvider extends ContentProvider { if (!ai.isInstantApp()) { return; } - if (!getEphemeralAccessibleSettings(settingsType).contains(settingName)) { + if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)) { throw new SecurityException("Setting " + settingName + " is not accessible from" + " ephemeral package " + getCallingPackage()); } diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java index 14abb537db9f..40499c96eb4b 100644 --- a/services/core/java/com/android/server/IntentResolver.java +++ b/services/core/java/com/android/server/IntentResolver.java @@ -351,7 +351,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } public List<R> queryIntentFromList(Intent intent, String resolvedType, boolean defaultOnly, - boolean visibleToEphemeral, boolean isEphemeral, ArrayList<F[]> listCut, int userId) { + ArrayList<F[]> listCut, int userId) { ArrayList<R> resultList = new ArrayList<R>(); final boolean debug = localLOGV || @@ -361,8 +361,8 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { final String scheme = intent.getScheme(); int N = listCut.size(); for (int i = 0; i < N; ++i) { - buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral, - isEphemeral, resolvedType, scheme, listCut.get(i), resultList, userId); + buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme, + listCut.get(i), resultList, userId); } filterResults(resultList); sortResults(resultList); @@ -370,7 +370,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly, - boolean visibleToEphemeral, boolean isEphemeral, int userId) { + int userId) { String scheme = intent.getScheme(); ArrayList<R> finalList = new ArrayList<R>(); @@ -443,20 +443,20 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { FastImmutableArraySet<String> categories = getFastIntentCategories(intent); if (firstTypeCut != null) { - buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral, - isEphemeral, resolvedType, scheme, firstTypeCut, finalList, userId); + buildResolveList(intent, categories, debug, defaultOnly, resolvedType, + scheme, firstTypeCut, finalList, userId); } if (secondTypeCut != null) { - buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral, - isEphemeral, resolvedType, scheme, secondTypeCut, finalList, userId); + buildResolveList(intent, categories, debug, defaultOnly, resolvedType, + scheme, secondTypeCut, finalList, userId); } if (thirdTypeCut != null) { - buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral, - isEphemeral, resolvedType, scheme, thirdTypeCut, finalList, userId); + buildResolveList(intent, categories, debug, defaultOnly, resolvedType, + scheme, thirdTypeCut, finalList, userId); } if (schemeCut != null) { - buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral, - isEphemeral, resolvedType, scheme, schemeCut, finalList, userId); + buildResolveList(intent, categories, debug, defaultOnly, resolvedType, + scheme, schemeCut, finalList, userId); } filterResults(finalList); sortResults(finalList); @@ -694,8 +694,8 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { } private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories, - boolean debug, boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, - String resolvedType, String scheme, F[] src, List<R> dest, int userId) { + boolean debug, boolean defaultOnly, String resolvedType, String scheme, + F[] src, List<R> dest, int userId) { final String action = intent.getAction(); final Uri data = intent.getData(); final String packageName = intent.getPackage(); @@ -735,15 +735,6 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { continue; } - // throw out filters that aren't visible to ephemeral apps - if (visibleToEphemeral && !filter.isVisibleToEphemeral()) { - continue; - } - // throw out ephemeral filters if we're not explicitly requesting them - if (!isEphemeral && filter.isEphemeral()) { - continue; - } - // Are we verified ? if (filter.getAutoVerify()) { if (localVerificationLOGV || debug) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c2c24b37a81a..4ba7eb2a68fe 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -231,6 +231,7 @@ import android.content.pm.PathPermission; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; +import android.content.pm.SELinuxUtil; import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.res.CompatibilityInfo; @@ -293,6 +294,7 @@ import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; import android.service.voice.VoiceInteractionSession; import android.telecom.TelecomManager; +import android.text.TextUtils; import android.text.format.DateUtils; import android.text.format.Time; import android.text.style.SuggestionSpan; @@ -3505,6 +3507,7 @@ public class ActivityManagerService extends IActivityManager.Stub info.processName = processName; info.className = entryPoint; info.packageName = "android"; + info.seInfoUser = SELinuxUtil.COMPLETE_STR; ProcessRecord proc = startProcessLocked(processName, info /* info */, false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, @@ -3776,6 +3779,13 @@ public class ActivityManagerService extends IActivityManager.Stub app.requiredAbi = requiredAbi; app.instructionSet = instructionSet; + // the per-user SELinux context must be set + if (TextUtils.isEmpty(app.info.seInfoUser)) { + Slog.wtf(TAG, "SELinux tag not defined", + new IllegalStateException("SELinux tag not defined")); + } + final String seInfo = app.info.seInfo + + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); // Start the process. It will either succeed and return a result containing // the PID of the new process, or else throw a RuntimeException. boolean isActivityProcess = (entryPoint == null); @@ -3787,12 +3797,12 @@ public class ActivityManagerService extends IActivityManager.Stub if (hostingType.equals("webview_service")) { startResult = Process.startWebView(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, - app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, + app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, null, entryPointArgs); } else { startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, - app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, + app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs); } checkTime(startTime, "startProcess: returned from zygote!"); @@ -3808,7 +3818,7 @@ public class ActivityManagerService extends IActivityManager.Stub try { AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, - app.info.seinfo, app.info.sourceDir, startResult.pid); + seInfo, app.info.sourceDir, startResult.pid); } catch (RemoteException ex) { // Ignore } @@ -18774,8 +18784,7 @@ public class ActivityManagerService extends IActivityManager.Stub } List<BroadcastFilter> registeredReceiversForUser = mReceiverResolver.queryIntent(intent, - resolvedType, false, false /*visibleToEphemeral*/, - false /*isInstant*/, users[i]); + resolvedType, false /*defaultOnly*/, users[i]); if (registeredReceivers == null) { registeredReceivers = registeredReceiversForUser; } else if (registeredReceiversForUser != null) { @@ -18784,8 +18793,7 @@ public class ActivityManagerService extends IActivityManager.Stub } } else { registeredReceivers = mReceiverResolver.queryIntent(intent, - resolvedType, false, false /*visibleToEphemeral*/, - false /*isInstant*/, userId); + resolvedType, false /*defaultOnly*/, userId); } } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 4a29872bdb72..df9323af6b45 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1199,7 +1199,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) { try { return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, - PackageManager.MATCH_DEFAULT_ONLY | flags + PackageManager.MATCH_INSTANT | PackageManager.MATCH_DEFAULT_ONLY | flags | ActivityManagerService.STOCK_PM_FLAGS, userId); } catch (RemoteException e) { } diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java index 93c14b94d27e..376a864e7772 100644 --- a/services/core/java/com/android/server/firewall/IntentFirewall.java +++ b/services/core/java/com/android/server/firewall/IntentFirewall.java @@ -151,8 +151,7 @@ public class IntentFirewall { // For the first pass, find all the rules that have at least one intent-filter or // component-filter that matches this intent List<Rule> candidateRules; - candidateRules = resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, - false /*visibleToEphemeral*/, false /*isInstant*/, 0); + candidateRules = resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, 0); if (candidateRules == null) { candidateRules = new ArrayList<Rule>(); } diff --git a/services/core/java/com/android/server/pm/EphemeralResolver.java b/services/core/java/com/android/server/pm/EphemeralResolver.java index 3c554221e17f..d99a1b685da3 100644 --- a/services/core/java/com/android/server/pm/EphemeralResolver.java +++ b/services/core/java/com/android/server/pm/EphemeralResolver.java @@ -234,8 +234,7 @@ public abstract class EphemeralResolver { } } List<EphemeralResponse> matchedResolveInfoList = ephemeralResolver.queryIntent( - intent, resolvedType, false /*defaultOnly*/, false /*visibleToEphemeral*/, - false /*isInstant*/, userId); + intent, resolvedType, false /*defaultOnly*/, userId); if (!matchedResolveInfoList.isEmpty()) { return matchedResolveInfoList.get(0); } diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java index 42934a43fb25..23925ad18f1b 100644 --- a/services/core/java/com/android/server/pm/InstantAppRegistry.java +++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java @@ -217,7 +217,7 @@ class InstantAppRegistry { propagateInstantAppPermissionsIfNeeded(pkg.packageName, userId); // Track instant apps - if (pkg.applicationInfo.isInstantApp()) { + if (ps.getInstantApp(userId)) { addInstantAppLPw(userId, ps.appId); } @@ -257,7 +257,7 @@ class InstantAppRegistry { continue; } - if (pkg.applicationInfo.isInstantApp()) { + if (ps.getInstantApp(userId)) { // Add a record for an uninstalled instant app addUninstalledInstantAppLPw(pkg, userId); removeInstantAppLPw(userId, ps.appId); @@ -533,11 +533,12 @@ class InstantAppRegistry { final int packageCount = mService.mPackages.size(); for (int i = 0; i < packageCount; i++) { - PackageParser.Package pkg = mService.mPackages.valueAt(i); - if (!pkg.applicationInfo.isInstantApp()) { + final PackageParser.Package pkg = mService.mPackages.valueAt(i); + final PackageSetting ps = (PackageSetting) pkg.mExtras; + if (ps == null || !ps.getInstantApp(userId)) { continue; } - InstantAppInfo info = createInstantAppInfoForPackage( + final InstantAppInfo info = createInstantAppInfoForPackage( pkg, userId, true); if (info == null) { continue; diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java index efd313237acf..eb42f809c0e8 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerService.java +++ b/services/core/java/com/android/server/pm/PackageInstallerService.java @@ -683,9 +683,9 @@ public class PackageInstallerService extends IPackageInstaller.Stub { File stageDir = null; String stageCid = null; if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) { - final boolean isEphemeral = - (params.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; - stageDir = buildStageDir(params.volumeUuid, sessionId, isEphemeral); + final boolean isInstant = + (params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; + stageDir = buildStageDir(params.volumeUuid, sessionId, isInstant); } else { stageCid = buildExternalStageCid(sessionId); } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 067a13642781..463cfac6127f 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -704,7 +704,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final ApkLite apk; try { int flags = PackageParser.PARSE_COLLECT_CERTIFICATES; - if ((params.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { + if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { flags |= PackageParser.PARSE_IS_EPHEMERAL; } apk = PackageParser.parseApkLite(addedFile, flags); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index f43e468f39ac..d54f68c497a1 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -41,7 +41,7 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS; import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER; import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION; -import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID; +import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID; import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR; import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK; @@ -164,6 +164,7 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; +import android.content.pm.SELinuxUtil; import android.content.pm.ServiceInfo; import android.content.pm.SharedLibraryInfo; import android.content.pm.Signature; @@ -421,8 +422,11 @@ public class PackageManagerService extends IPackageManager.Stub { static final int SCAN_CHECK_ONLY = 1<<13; static final int SCAN_DONT_KILL_APP = 1<<14; static final int SCAN_IGNORE_FROZEN = 1<<15; - static final int REMOVE_CHATTY = 1<<16; - static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<17; + static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16; + static final int SCAN_AS_INSTANT_APP = 1<<17; + static final int SCAN_AS_FULL_APP = 1<<18; + /** Should not be with the scan flags */ + static final int FLAGS_REMOVE_CHATTY = 1<<31; private static final String STATIC_SHARED_LIB_DELIMITER = "_"; @@ -1776,28 +1780,32 @@ public class PackageManagerService extends IPackageManager.Stub { // the first time vs. those who are seeing an update. int[] firstUsers = EMPTY_INT_ARRAY; int[] updateUsers = EMPTY_INT_ARRAY; - if (res.origUsers == null || res.origUsers.length == 0) { - firstUsers = res.newUsers; - } else { - for (int newUser : res.newUsers) { - boolean isNew = true; - for (int origUser : res.origUsers) { - if (origUser == newUser) { - isNew = false; - break; - } - } - if (isNew) { - firstUsers = ArrayUtils.appendInt(firstUsers, newUser); - } else { - updateUsers = ArrayUtils.appendInt(updateUsers, newUser); + final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0; + final PackageSetting ps = (PackageSetting) res.pkg.mExtras; + for (int newUser : res.newUsers) { + if (ps.getInstantApp(newUser)) { + continue; + } + if (allNewUsers) { + firstUsers = ArrayUtils.appendInt(firstUsers, newUser); + continue; + } + boolean isNew = true; + for (int origUser : res.origUsers) { + if (origUser == newUser) { + isNew = false; + break; } } + if (isNew) { + firstUsers = ArrayUtils.appendInt(firstUsers, newUser); + } else { + updateUsers = ArrayUtils.appendInt(updateUsers, newUser); + } } - // Send installed broadcasts if the install/update is not ephemeral - // and the package is not a static shared lib. - if (!isEphemeral(res.pkg) && res.pkg.staticSharedLibName == null) { + // Send installed broadcasts if the package is not a static shared lib. + if (res.pkg.staticSharedLibName == null) { mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath); // Send added for users that see the package for the first time @@ -1884,16 +1892,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } - if (!isEphemeral(res.pkg)) { - // Notify DexManager that the package was installed for new users. - // The updated users should already be indexed and the package code paths - // should not change. - // Don't notify the manager for ephemeral apps as they are not expected to - // survive long enough to benefit of background optimizations. - for (int userId : firstUsers) { - PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); - mDexManager.notifyPackageInstalled(info, userId); - } + // Notify DexManager that the package was installed for new users. + // The updated users should already be indexed and the package code paths + // should not change. + // Don't notify the manager for ephemeral apps as they are not expected to + // survive long enough to benefit of background optimizations. + for (int userId : firstUsers) { + PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId); + mDexManager.notifyPackageInstalled(info, userId); } } @@ -3332,14 +3338,14 @@ public class PackageManagerService extends IPackageManager.Stub { && callingAppId != Process.ROOT_UID && checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS, Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) { - final String ephemeralPackageName = getEphemeralPackageName(Binder.getCallingUid()); - if (ephemeralPackageName != null) { + final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid()); + if (instantAppPackageName != null) { // ephemeral apps can only get information on themselves - if (!ephemeralPackageName.equals(p.packageName)) { + if (!instantAppPackageName.equals(p.packageName)) { return null; } } else { - if (p.applicationInfo.isInstantApp()) { + if (ps.getInstantApp(userId)) { // only get access to the ephemeral app if we've been granted access if (!mInstantAppRegistry.isInstantAccessGranted( userId, callingAppId, ps.appId)) { @@ -3950,17 +3956,17 @@ public class PackageManagerService extends IPackageManager.Stub { flags |= PackageManager.MATCH_SYSTEM_ONLY; } final int callingUid = Binder.getCallingUid(); - if (callingUid == Process.SYSTEM_UID || callingUid == 0) { - // The system sees all components - flags |= PackageManager.MATCH_EPHEMERAL; - } else if (getEphemeralPackageName(callingUid) != null) { + if (getInstantAppPackageName(callingUid) != null) { // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components - flags |= PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY; - flags |= PackageManager.MATCH_EPHEMERAL; + flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; + flags |= PackageManager.MATCH_INSTANT; } else { // Otherwise, prevent leaking ephemeral components - flags &= ~PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY; - flags &= ~PackageManager.MATCH_EPHEMERAL; + flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY; + if (callingUid != Process.SYSTEM_UID && callingUid != 0) { + // Unless called from the system process + flags &= ~PackageManager.MATCH_INSTANT; + } } return updateFlagsForComponent(flags, userId, cookie); } @@ -4689,7 +4695,8 @@ public class PackageManagerService extends IPackageManager.Stub { return; } - if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) { + final PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps.getInstantApp(userId) && !bp.isInstant()) { throw new SecurityException("Cannot grant non-ephemeral permission" + name + " for package " + packageName); } @@ -5738,8 +5745,7 @@ public class PackageManagerService extends IPackageManager.Stub { List<PersistentPreferredActivity> pprefs = ppir != null ? ppir.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, - (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId) + userId) : null; if (pprefs != null && pprefs.size() > 0) { final int M = pprefs.size(); @@ -5811,8 +5817,7 @@ public class PackageManagerService extends IPackageManager.Stub { List<PreferredActivity> prefs = pir != null ? pir.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, - (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId) + userId) : null; if (prefs != null && prefs.size() > 0) { boolean changed = false; @@ -5983,8 +5988,7 @@ public class PackageManagerService extends IPackageManager.Stub { String resolvedType, int userId) { CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId); if (resolver != null) { - return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, - false /*visibleToEphemeral*/, false /*isInstant*/, userId); + return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId); } return null; } @@ -6003,16 +6007,17 @@ public class PackageManagerService extends IPackageManager.Stub { } /** - * Returns the package name of the calling Uid if it's an ephemeral app. If it isn't - * ephemeral, returns {@code null}. + * Returns the package name of the calling Uid if it's an instant app. If it isn't + * instant, returns {@code null}. */ - private String getEphemeralPackageName(int callingUid) { + private String getInstantAppPackageName(int callingUid) { final int appId = UserHandle.getAppId(callingUid); synchronized (mPackages) { final Object obj = mSettings.getUserIdLPr(appId); if (obj instanceof PackageSetting) { final PackageSetting ps = (PackageSetting) obj; - return ps.pkg.applicationInfo.isInstantApp() ? ps.pkg.packageName : null; + final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid)); + return isInstantApp ? ps.pkg.packageName : null; } } return null; @@ -6021,7 +6026,7 @@ public class PackageManagerService extends IPackageManager.Stub { private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); - final String ephemeralPkgName = getEphemeralPackageName(Binder.getCallingUid()); + final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid()); flags = updateFlagsForResolve(flags, userId, intent); enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission */, false /* checkShell */, @@ -6043,14 +6048,14 @@ public class PackageManagerService extends IPackageManager.Stub { // an ephemeral application or 2) the calling package is ephemeral and the // activity is not visible to ephemeral applications. boolean matchEphemeral = - (flags & PackageManager.MATCH_EPHEMERAL) != 0; + (flags & PackageManager.MATCH_INSTANT) != 0; boolean ephemeralVisibleOnly = - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; + (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; boolean blockResolution = - (!matchEphemeral && ephemeralPkgName == null + (!matchEphemeral && instantAppPkgName == null && (ai.applicationInfo.privateFlags - & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0) - || (ephemeralVisibleOnly && ephemeralPkgName != null + & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0) + || (ephemeralVisibleOnly && instantAppPkgName != null && (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0); if (!blockResolution) { final ResolveInfo ri = new ResolveInfo(); @@ -6077,7 +6082,7 @@ public class PackageManagerService extends IPackageManager.Stub { List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1); xpResult.add(xpResolveInfo); return filterForEphemeral( - filterIfNotSystemUser(xpResult, userId), ephemeralPkgName); + filterIfNotSystemUser(xpResult, userId), instantAppPkgName); } // Check for results in the current profile. @@ -6117,13 +6122,13 @@ public class PackageManagerService extends IPackageManager.Stub { // And we are not going to add emphemeral app, so we can return the // result straight away. result.add(xpDomainInfo.resolveInfo); - return filterForEphemeral(result, ephemeralPkgName); + return filterForEphemeral(result, instantAppPkgName); } } else if (result.size() <= 1 && !addEphemeral) { // No result in parent user and <= 1 result in current profile, and we // are not going to add emphemeral app, so we can return the result without // further processing. - return filterForEphemeral(result, ephemeralPkgName); + return filterForEphemeral(result, instantAppPkgName); } // We have more than one candidate (combining results from current and parent // profile), so we need filtering and sorting. @@ -6137,7 +6142,7 @@ public class PackageManagerService extends IPackageManager.Stub { result = filterForEphemeral(filterIfNotSystemUser( mActivities.queryIntentForPackage( intent, resolvedType, flags, pkg.activities, userId), - userId), ephemeralPkgName); + userId), instantAppPkgName); } else { // the caller wants to resolve for a particular package; however, there // were no installed results, so, try to find an ephemeral result @@ -6175,7 +6180,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (sortResult) { Collections.sort(result, mResolvePrioritySorter); } - return filterForEphemeral(result, ephemeralPkgName); + return filterForEphemeral(result, instantAppPkgName); } private static class CrossProfileDomainInfo { @@ -7139,9 +7144,9 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } synchronized (mPackages) { - PackageParser.Package pkg = mPackages.get(packageName); - if (pkg != null) { - return pkg.applicationInfo.isInstantApp(); + final PackageSetting ps = mSettings.mPackages.get(packageName); + if (ps != null) { + return ps.getInstantApp(userId); } } return false; @@ -7644,7 +7649,7 @@ public class PackageManagerService extends IPackageManager.Stub { * @throws PackageManagerException on a parse error. */ private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile, - final int policyFlags, int scanFlags, long currentTime, UserHandle user) + final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { // If the package has children and this is the first dive in the function // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all @@ -7684,7 +7689,7 @@ public class PackageManagerService extends IPackageManager.Stub { * @throws PackageManagerException on a parse error. */ private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile, - int policyFlags, int scanFlags, long currentTime, UserHandle user) + int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { PackageSetting ps = null; PackageSetting updatedPkg; @@ -7920,6 +7925,11 @@ public class PackageManagerService extends IPackageManager.Stub { pkg.setApplicationInfoBaseResourcePath(baseResourcePath); pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths); + final int userId = ((user == null) ? 0 : user.getIdentifier()); + if (ps != null && ps.getInstantApp(userId)) { + scanFlags |= SCAN_AS_INSTANT_APP; + } + // Note that we invoke the following method only if we are about to unpack an application PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags | SCAN_UPDATE_SIGNATURE, currentTime, user); @@ -8857,7 +8867,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg, - final int policyFlags, int scanFlags, long currentTime, UserHandle user) + final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage"); // If the package has children and this is the first dive in the function @@ -8896,7 +8906,8 @@ public class PackageManagerService extends IPackageManager.Stub { } private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags, - int scanFlags, long currentTime, UserHandle user) throws PackageManagerException { + int scanFlags, long currentTime, @Nullable UserHandle user) + throws PackageManagerException { boolean success = false; try { final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags, @@ -8962,7 +8973,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg, - final int policyFlags, final int scanFlags, long currentTime, UserHandle user) + final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user) throws PackageManagerException { if (DEBUG_PACKAGE_SCANNING) { if ((policyFlags & PackageParser.PARSE_CHATTY) != 0) @@ -9100,16 +9111,16 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkgSetting == null) { final String parentPackageName = (pkg.parentPackage != null) ? pkg.parentPackage.packageName : null; - + final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; // REMOVE SharedUserSetting from method; update in a separate call pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage, disabledPkgSetting, realName, suid, destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user, - true /*allowInstall*/, parentPackageName, pkg.getChildPackageNames(), - UserManagerService.getInstance(), usesStaticLibraries, - pkg.usesStaticLibrariesVersions); + true /*allowInstall*/, instantApp, parentPackageName, + pkg.getChildPackageNames(), UserManagerService.getInstance(), + usesStaticLibraries, pkg.usesStaticLibrariesVersions); // SIDE EFFECTS; updates system state; move elsewhere if (origPackage != null) { mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name); @@ -9176,9 +9187,8 @@ public class PackageManagerService extends IPackageManager.Stub { } if (mFoundPolicyFile) { - SELinuxMMAC.assignSeinfoValue(pkg); + SELinuxMMAC.assignSeInfoValue(pkg); } - pkg.applicationInfo.uid = pkgSetting.appId; pkg.mExtras = pkgSetting; @@ -9413,11 +9423,11 @@ public class PackageManagerService extends IPackageManager.Stub { } } } else { + final int userId = user == null ? 0 : user.getIdentifier(); // Modify state for the given package setting commitPackageSettings(pkg, pkgSetting, user, scanFlags, (policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/); - if (isEphemeral(pkg)) { - final int userId = user == null ? 0 : user.getIdentifier(); + if (pkgSetting.getInstantApp(userId)) { mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId); } } @@ -9532,10 +9542,10 @@ public class PackageManagerService extends IPackageManager.Stub { "Packages declaring static-shared libs must target O SDK or higher"); } - // Package declaring static a shared lib cannot be ephemeral - if (pkg.applicationInfo.isInstantApp()) { + // Package declaring static a shared lib cannot be instant apps + if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { throw new PackageManagerException( - "Packages declaring static-shared libs cannot be ephemeral"); + "Packages declaring static-shared libs cannot be instant apps"); } // Package declaring static a shared lib cannot be renamed since the package @@ -9778,7 +9788,6 @@ public class PackageManagerService extends IPackageManager.Stub { mPlatformPackage = pkg; pkg.mVersionCode = mSdkVersion; mAndroidApplication = pkg.applicationInfo; - if (!mResolverReplaced) { mResolveActivity.applicationInfo = mAndroidApplication; mResolveActivity.name = ResolverActivity.class.getName(); @@ -10067,10 +10076,10 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name); final String curPackageName = cur == null ? null : cur.info.packageName; // Dont allow ephemeral apps to define new permission groups. - if (pkg.applicationInfo.isInstantApp()) { + if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission group " + pg.info.name + " from package " + pg.info.packageName - + " ignored: ephemeral apps cannot define new permission groups."); + + " ignored: instant apps cannot define new permission groups."); continue; } final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName); @@ -10112,10 +10121,10 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Permission p = pkg.permissions.get(i); // Dont allow ephemeral apps to define new permissions. - if (pkg.applicationInfo.isInstantApp()) { + if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName - + " ignored: ephemeral apps cannot define new permissions."); + + " ignored: instant apps cannot define new permissions."); continue; } @@ -11737,13 +11746,10 @@ public class PackageManagerService extends IPackageManager.Stub { final class ActivityIntentResolver extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> { public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, - boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { + boolean defaultOnly, int userId) { if (!sUserManager.exists(userId)) return null; - mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0) - | (visibleToEphemeral ? PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY : 0) - | (isEphemeral ? PackageManager.MATCH_EPHEMERAL : 0); - return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, - isEphemeral, userId); + mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0); + return super.queryIntent(intent, resolvedType, defaultOnly, userId); } public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, @@ -11752,8 +11758,7 @@ public class PackageManagerService extends IPackageManager.Stub { mFlags = flags; return super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, - (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); + userId); } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, @@ -11764,9 +11769,6 @@ public class PackageManagerService extends IPackageManager.Stub { } mFlags = flags; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; - final boolean vislbleToEphemeral = - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; - final boolean isEphemeral = (flags & PackageManager.MATCH_EPHEMERAL) != 0; final int N = packageActivities.size(); ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<PackageParser.ActivityIntentInfo[]>(N); @@ -11781,8 +11783,7 @@ public class PackageManagerService extends IPackageManager.Stub { listCut.add(array); } } - return super.queryIntentFromList(intent, resolvedType, defaultOnly, - vislbleToEphemeral, isEphemeral, listCut, userId); + return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } /** @@ -12194,11 +12195,24 @@ public class PackageManagerService extends IPackageManager.Stub { if (ps == null) { return null; } + final PackageUserState userState = ps.readUserState(userId); ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags, - ps.readUserState(userId), userId); + userState, userId); if (ai == null) { return null; } + final boolean matchVisibleToInstantApp = + (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; + final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0; + // throw out filters that aren't visible to ephemeral apps + if (matchVisibleToInstantApp + && !(info.isVisibleToInstantApp() || userState.instantApp)) { + return null; + } + // throw out ephemeral filters if we're not explicitly requesting them + if (!isInstantApp && userState.instantApp) { + return null; + } final ResolveInfo res = new ResolveInfo(); res.activityInfo = ai; if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) { @@ -12267,10 +12281,9 @@ public class PackageManagerService extends IPackageManager.Stub { private final class ServiceIntentResolver extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> { public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, - boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { + boolean defaultOnly, int userId) { mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; - return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, - isEphemeral, userId); + return super.queryIntent(intent, resolvedType, defaultOnly, userId); } public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, @@ -12279,8 +12292,7 @@ public class PackageManagerService extends IPackageManager.Stub { mFlags = flags; return super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, - (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); + userId); } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, @@ -12291,9 +12303,6 @@ public class PackageManagerService extends IPackageManager.Stub { } mFlags = flags; final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0; - final boolean vislbleToEphemeral = - (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; - final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0; final int N = packageServices.size(); ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<PackageParser.ServiceIntentInfo[]>(N); @@ -12308,8 +12317,7 @@ public class PackageManagerService extends IPackageManager.Stub { listCut.add(array); } } - return super.queryIntentFromList(intent, resolvedType, defaultOnly, - vislbleToEphemeral, isEphemeral, listCut, userId); + return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } public final void addService(PackageParser.Service s) { @@ -12484,10 +12492,9 @@ public class PackageManagerService extends IPackageManager.Stub { private final class ProviderIntentResolver extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> { public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, - boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) { + boolean defaultOnly, int userId) { mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0; - return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral, - isEphemeral, userId); + return super.queryIntent(intent, resolvedType, defaultOnly, userId); } public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags, @@ -12497,8 +12504,7 @@ public class PackageManagerService extends IPackageManager.Stub { mFlags = flags; return super.queryIntent(intent, resolvedType, (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, - (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0, - (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId); + userId); } public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType, @@ -12510,9 +12516,6 @@ public class PackageManagerService extends IPackageManager.Stub { } mFlags = flags; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; - final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0; - final boolean vislbleToEphemeral = - (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0; final int N = packageProviders.size(); ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<PackageParser.ProviderIntentInfo[]>(N); @@ -12527,8 +12530,7 @@ public class PackageManagerService extends IPackageManager.Stub { listCut.add(array); } } - return super.queryIntentFromList(intent, resolvedType, defaultOnly, - vislbleToEphemeral, isEphemeral, listCut, userId); + return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } public final void addProvider(PackageParser.Provider p) { @@ -13069,7 +13071,7 @@ public class PackageManagerService extends IPackageManager.Stub { String installerPackageName, int installerUid, UserHandle user, Certificate[][] certificates) { if (DEBUG_EPHEMERAL) { - if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { + if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { Slog.d(TAG, "Ephemeral install of " + packageName); } } @@ -13284,7 +13286,8 @@ public class PackageManagerService extends IPackageManager.Stub { * @hide */ @Override - public int installExistingPackageAsUser(String packageName, int userId, int installReason) { + public int installExistingPackageAsUser(String packageName, int userId, int installFlags, + int installReason) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); PackageSetting pkgSetting; @@ -13299,6 +13302,10 @@ public class PackageManagerService extends IPackageManager.Stub { long callingId = Binder.clearCallingIdentity(); try { boolean installed = false; + final boolean instantApp = + (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; + final boolean fullApp = + (installFlags & PackageManager.INSTALL_FULL_APP) != 0; // writer synchronized (mPackages) { @@ -13313,7 +13320,11 @@ public class PackageManagerService extends IPackageManager.Stub { mSettings.writePackageRestrictionsLPr(userId); mSettings.writeKernelMappingLPr(pkgSetting); installed = true; + } else if (fullApp && pkgSetting.getInstantApp(userId)) { + // upgrade app from instant to full; we don't allow app downgrade + installed = true; } + setInstantAppForUser(pkgSetting, userId, instantApp, fullApp); } if (installed) { @@ -13335,6 +13346,29 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.INSTALL_SUCCEEDED; } + void setInstantAppForUser(PackageSetting pkgSetting, int userId, + boolean instantApp, boolean fullApp) { + // no state specified; do nothing + if (!instantApp && !fullApp) { + return; + } + if (userId != UserHandle.USER_ALL) { + if (instantApp && !pkgSetting.getInstantApp(userId)) { + pkgSetting.setInstantApp(true /*instantApp*/, userId); + } else if (fullApp && pkgSetting.getInstantApp(userId)) { + pkgSetting.setInstantApp(false /*instantApp*/, userId); + } + } else { + for (int currentUserId : sUserManager.getUserIds()) { + if (instantApp && !pkgSetting.getInstantApp(currentUserId)) { + pkgSetting.setInstantApp(true /*instantApp*/, currentUserId); + } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) { + pkgSetting.setInstantApp(false /*instantApp*/, currentUserId); + } + } + } + } + boolean isUserRestricted(int userId, String restrictionKey) { Bundle restrictions = sUserManager.getUserRestrictions(userId); if (restrictions.getBoolean(restrictionKey, false)) { @@ -13693,7 +13727,7 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } // Ephemeral apps don't get the full verification treatment - if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) { + if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) { if (DEBUG_EPHEMERAL) { Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification"); } @@ -14485,7 +14519,7 @@ public class PackageManagerService extends IPackageManager.Stub { final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0; final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0; - final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; + final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; PackageInfoLite pkgLite = null; if (onInt && onSd) { @@ -14569,7 +14603,7 @@ public class PackageManagerService extends IPackageManager.Stub { if (DEBUG_EPHEMERAL) { Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag"); } - installFlags |= PackageManager.INSTALL_EPHEMERAL; + installFlags |= PackageManager.INSTALL_INSTANT_APP; installFlags &= ~(PackageManager.INSTALL_EXTERNAL |PackageManager.INSTALL_INTERNAL); } else { @@ -14903,7 +14937,7 @@ public class PackageManagerService extends IPackageManager.Stub { } protected boolean isEphemeral() { - return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; + return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; } UserHandle getUser() { @@ -14983,7 +15017,7 @@ public class PackageManagerService extends IPackageManager.Stub { } try { - final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0; + final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0; final File tempDir = mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral); codeFile = tempDir; @@ -15810,7 +15844,7 @@ public class PackageManagerService extends IPackageManager.Stub { private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags, UserHandle user, String installerPackageName, PackageInstalledInfo res, int installReason) { - final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0; + final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; final PackageParser.Package oldPackage; final String pkgName = pkg.packageName; @@ -15834,17 +15868,17 @@ public class PackageManagerService extends IPackageManager.Stub { return; } + final PackageSetting ps = mSettings.mPackages.get(pkgName); + // don't allow an upgrade from full to ephemeral - final boolean oldIsEphemeral = oldPackage.applicationInfo.isInstantApp(); - if (isEphemeral && !oldIsEphemeral) { - // can't downgrade from full to ephemeral - Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName); - res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); + if (isInstantApp && !ps.getInstantApp(user.getIdentifier())) { + // can't downgrade from full to instant + Slog.w(TAG, "Can't replace app with instant app: " + pkgName); + res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); return; } // verify signatures are valid - final PackageSetting ps = mSettings.mPackages.get(pkgName); if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) { if (!checkUpgradeKeySetLP(ps, pkg)) { res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE, @@ -16046,6 +16080,10 @@ public class PackageManagerService extends IPackageManager.Stub { childPs.oldCodePaths = ps.oldCodePaths; } } + // set instant app status, but, only if it's explicitly specified + final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0; + final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0; + setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp); prepareAppDataAfterInstallLIF(newPackage); addedPkg = true; } catch (PackageManagerException e) { @@ -16517,7 +16555,8 @@ public class PackageManagerService extends IPackageManager.Stub { final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0); final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) || (args.volumeUuid != null)); - final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0); + final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0); + final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0); final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0); boolean replace = false; int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; @@ -16528,6 +16567,12 @@ public class PackageManagerService extends IPackageManager.Stub { if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) { scanFlags |= SCAN_DONT_KILL_APP; } + if (instantApp) { + scanFlags |= SCAN_AS_INSTANT_APP; + } + if (fullApp) { + scanFlags |= SCAN_AS_FULL_APP; + } // Result object to be returned res.setReturnCode(PackageManager.INSTALL_SUCCEEDED); @@ -16535,10 +16580,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile); // Sanity check - if (ephemeral && (forwardLocked || onExternal)) { + if (instantApp && (forwardLocked || onExternal)) { Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked + " external=" + onExternal); - res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID); + res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID); return; } @@ -16547,7 +16592,7 @@ public class PackageManagerService extends IPackageManager.Stub { | PackageParser.PARSE_ENFORCE_CODE | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0) - | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0) + | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0) | (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0); PackageParser pp = new PackageParser(); pp.setSeparateProcesses(mSeparateProcesses); @@ -16566,7 +16611,7 @@ public class PackageManagerService extends IPackageManager.Stub { // // Ephemeral apps must have target SDK >= O. // // TODO: Update conditional and error message when O gets locked down -// if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { +// if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) { // res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID, // "Ephemeral apps must have target SDK version of at least O"); // return; @@ -16809,10 +16854,10 @@ public class PackageManagerService extends IPackageManager.Stub { res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION, "Cannot install updates to system apps on sdcard"); return; - } else if (ephemeral) { - // Abort update; system app can't be replaced with an ephemeral app - res.setError(INSTALL_FAILED_EPHEMERAL_INVALID, - "Cannot update a system app with an ephemeral app"); + } else if (instantApp) { + // Abort update; system app can't be replaced with an instant app + res.setError(INSTALL_FAILED_INSTANT_APP_INVALID, + "Cannot update a system app with an instant app"); return; } } @@ -17059,14 +17104,6 @@ public class PackageManagerService extends IPackageManager.Stub { return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } - private static boolean isEphemeral(PackageParser.Package pkg) { - return pkg.applicationInfo.isInstantApp(); - } - - private static boolean isEphemeral(PackageSetting ps) { - return ps.pkg != null && isEphemeral(ps.pkg); - } - private static boolean isSystemApp(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @@ -17089,9 +17126,6 @@ public class PackageManagerService extends IPackageManager.Stub { private int packageFlagsToInstallFlags(PackageSetting ps) { int installFlags = 0; - if (isEphemeral(ps)) { - installFlags |= PackageManager.INSTALL_EPHEMERAL; - } if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) { // This existing package was an external ASEC install when we have // the external flag without a UUID @@ -17493,7 +17527,7 @@ public class PackageManagerService extends IPackageManager.Stub { try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser, deleteFlags, "deletePackageX")) { res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers, - deleteFlags | REMOVE_CHATTY, info, true, null); + deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null); } synchronized (mPackages) { if (res) { @@ -17643,7 +17677,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - removePackageLI(ps, (flags & REMOVE_CHATTY) != 0); + removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0); if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) { final PackageParser.Package resolvedPkg; @@ -18202,11 +18236,18 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId); } ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT, - false /*installed*/, true /*stopped*/, true /*notLaunched*/, - false /*hidden*/, false /*suspended*/, null, null, null, + false /*installed*/, + true /*stopped*/, + true /*notLaunched*/, + false /*hidden*/, + false /*suspended*/, + false /*instantApp*/, + null /*lastDisableAppCaller*/, + null /*enabledComponents*/, + null /*disabledComponents*/, false /*blockUninstall*/, - ps.readUserState(nextUserId).domainVerificationStatus, 0, - PackageManager.INSTALL_REASON_UNKNOWN); + ps.readUserState(nextUserId).domainVerificationStatus, + 0, PackageManager.INSTALL_REASON_UNKNOWN); } mSettings.writeKernelMappingLPr(ps); } @@ -21688,12 +21729,12 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); final ApplicationInfo app = pkg.applicationInfo; final int appId = UserHandle.getAppId(app.uid); - Preconditions.checkNotNull(app.seinfo); + Preconditions.checkNotNull(app.seInfo); long ceDataInode = -1; try { ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, - appId, app.seinfo, app.targetSdkVersion); + appId, app.seInfo, app.targetSdkVersion); } catch (InstallerException e) { if (app.isSystemApp()) { logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName @@ -21701,7 +21742,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); destroyAppDataLeafLIF(pkg, userId, flags); try { ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags, - appId, app.seinfo, app.targetSdkVersion); + appId, app.seInfo, app.targetSdkVersion); logCriticalInfo(Log.DEBUG, "Recovery succeeded!"); } catch (InstallerException e2) { logCriticalInfo(Log.DEBUG, "Recovery failed!"); @@ -22003,7 +22044,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); installerPackageName = ps.installerPackageName; packageAbiOverride = ps.cpuAbiOverrideString; appId = UserHandle.getAppId(pkg.applicationInfo.uid); - seinfo = pkg.applicationInfo.seinfo; + seinfo = pkg.applicationInfo.seInfo; label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo)); targetSdkVersion = pkg.applicationInfo.targetSdkVersion; freezer = freezePackage(packageName, "movePackageInternal"); @@ -22812,8 +22853,8 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); @Override public boolean isPackageEphemeral(int userId, String packageName) { synchronized (mPackages) { - PackageParser.Package p = mPackages.get(packageName); - return p != null ? p.applicationInfo.isInstantApp() : false; + final PackageSetting ps = mSettings.mPackages.get(packageName); + return ps != null ? ps.getInstantApp(userId) : false; } } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 1203e4d58c00..a7349fc8454c 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -39,6 +39,7 @@ import android.content.pm.PermissionGroupInfo; import android.content.pm.PermissionInfo; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageInstaller.SessionParams; +import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ResolveInfo; import android.content.pm.VersionedPackage; import android.content.res.AssetManager; @@ -116,6 +117,8 @@ class PackageManagerShellCommand extends ShellCommand { return runInstallRemove(); case "install-write": return runInstallWrite(); + case "install-existing": + return runInstallExisting(); case "compile": return runCompile(); case "reconcile-secondary-dex-files": @@ -301,6 +304,51 @@ class PackageManagerShellCommand extends ShellCommand { return doRemoveSplit(sessionId, splitName, true /*logSuccess*/); } + private int runInstallExisting() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + int userId = UserHandle.USER_SYSTEM; + int installFlags = 0; + String opt; + while ((opt = getNextOption()) != null) { + switch (opt) { + case "--user": + userId = UserHandle.parseUserArg(getNextArgRequired()); + break; + case "--ephemeral": + case "--instant": + installFlags |= PackageManager.INSTALL_INSTANT_APP; + installFlags &= ~PackageManager.INSTALL_FULL_APP; + break; + case "--full": + installFlags &= ~PackageManager.INSTALL_INSTANT_APP; + installFlags |= PackageManager.INSTALL_FULL_APP; + break; + default: + pw.println("Error: Unknown option: " + opt); + return 1; + } + } + + final String packageName = getNextArg(); + if (packageName == null) { + pw.println("Error: package name not specified"); + return 1; + } + + try { + final int res = mInterface.installExistingPackageAsUser(packageName, userId, + installFlags, PackageManager.INSTALL_REASON_UNKNOWN); + if (res == PackageManager.INSTALL_FAILED_INVALID_URI) { + throw new NameNotFoundException("Package " + packageName + " doesn't exist"); + } + pw.println("Package " + packageName + " installed for user: " + userId); + return 0; + } catch (RemoteException | NameNotFoundException e) { + pw.println(e.toString()); + return 1; + } + } + private int runCompile() throws RemoteException { final PrintWriter pw = getOutPrintWriter(); boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false); @@ -1145,8 +1193,12 @@ class PackageManagerShellCommand extends ShellCommand { sessionParams.abiOverride = checkAbiArgument(getNextArg()); break; case "--ephemeral": + case "--instantapp": sessionParams.setInstallAsInstantApp(true /*isInstantApp*/); break; + case "--full": + sessionParams.setInstallAsInstantApp(false /*isInstantApp*/); + break; case "--user": params.userId = UserHandle.parseUserArg(getNextArgRequired()); break; diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index 0e11b0cec4c2..601377d6f8d2 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -397,11 +397,19 @@ abstract class PackageSettingBase extends SettingBase { modifyUserState(userId).blockUninstall = blockUninstall; } + boolean getInstantApp(int userId) { + return readUserState(userId).instantApp; + } + + void setInstantApp(boolean instantApp, int userId) { + modifyUserState(userId).instantApp = instantApp; + } + void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped, - boolean notLaunched, boolean hidden, boolean suspended, + boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp, String lastDisableAppCaller, ArraySet<String> enabledComponents, - ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState, - int linkGeneration, int installReason) { + ArraySet<String> disabledComponents, boolean blockUninstall, + int domainVerifState, int linkGeneration, int installReason) { PackageUserState state = modifyUserState(userId); state.ceDataInode = ceDataInode; state.enabled = enabled; @@ -417,6 +425,7 @@ abstract class PackageSettingBase extends SettingBase { state.domainVerificationStatus = domainVerifState; state.appLinkGeneration = linkGeneration; state.installReason = installReason; + state.instantApp = instantApp; } ArraySet<String> getEnabledComponents(int userId) { diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java index 7e7de21eb982..188e66f8cf27 100644 --- a/services/core/java/com/android/server/pm/SELinuxMMAC.java +++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java @@ -17,6 +17,8 @@ package com.android.server.pm; import android.content.pm.PackageParser; +import android.content.pm.PackageUserState; +import android.content.pm.SELinuxUtil; import android.content.pm.Signature; import android.os.Environment; import android.util.Slog; @@ -69,9 +71,6 @@ public final class SELinuxMMAC { // Append v2 to existing seinfo label private static final String SANDBOX_V2_STR = ":v2"; - // Append ephemeral to existing seinfo label - private static final String EPHEMERAL_APP_STR = ":ephemeralapp"; - // Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion private static final String TARGETSDKVERSION_STR = ":targetSdkVersion="; @@ -279,31 +278,28 @@ public final class SELinuxMMAC { * * @param pkg object representing the package to be labeled. */ - public static void assignSeinfoValue(PackageParser.Package pkg) { + public static void assignSeInfoValue(PackageParser.Package pkg) { synchronized (sPolicies) { for (Policy policy : sPolicies) { - String seinfo = policy.getMatchedSeinfo(pkg); - if (seinfo != null) { - pkg.applicationInfo.seinfo = seinfo; + String seInfo = policy.getMatchedSeInfo(pkg); + if (seInfo != null) { + pkg.applicationInfo.seInfo = seInfo; break; } } } - if (pkg.applicationInfo.isInstantApp()) - pkg.applicationInfo.seinfo += EPHEMERAL_APP_STR; - if (pkg.applicationInfo.targetSandboxVersion == 2) - pkg.applicationInfo.seinfo += SANDBOX_V2_STR; + pkg.applicationInfo.seInfo += SANDBOX_V2_STR; if (pkg.applicationInfo.isPrivilegedApp()) - pkg.applicationInfo.seinfo += PRIVILEGED_APP_STR; + pkg.applicationInfo.seInfo += PRIVILEGED_APP_STR; - pkg.applicationInfo.seinfo += TARGETSDKVERSION_STR + pkg.applicationInfo.targetSdkVersion; + pkg.applicationInfo.seInfo += TARGETSDKVERSION_STR + pkg.applicationInfo.targetSdkVersion; if (DEBUG_POLICY_INSTALL) { Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " + - "seinfo=" + pkg.applicationInfo.seinfo); + "seinfo=" + pkg.applicationInfo.seInfo); } } } @@ -438,7 +434,7 @@ final class Policy { * @return A string representing the seinfo matched during policy lookup. * A value of null can also be returned if no match occured. */ - public String getMatchedSeinfo(PackageParser.Package pkg) { + public String getMatchedSeInfo(PackageParser.Package pkg) { // Check for exact signature matches across all certs. Signature[] certs = mCerts.toArray(new Signature[0]); if (!Signature.areExactMatch(certs, pkg.mSignatures)) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 61568022eff2..a8a5ff056521 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -219,6 +219,7 @@ final class Settings { private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus"; private static final String ATTR_APP_LINK_GENERATION = "app-link-generation"; private static final String ATTR_INSTALL_REASON = "install-reason"; + private static final String ATTR_INSTANT_APP = "instant-app"; private static final String ATTR_PACKAGE_NAME = "packageName"; private static final String ATTR_FINGERPRINT = "fingerprint"; @@ -687,7 +688,7 @@ final class Settings { PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser, File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi, String secondaryCpuAbi, int versionCode, int pkgFlags, int pkgPrivateFlags, - UserHandle installUser, boolean allowInstall, String parentPkgName, + UserHandle installUser, boolean allowInstall, boolean instantApp, String parentPkgName, List<String> childPkgNames, UserManagerService userManager, String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) { final PackageSetting pkgSetting; @@ -745,14 +746,17 @@ final class Settings { || installUserId == user.id; pkgSetting.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT, installed, - true, // stopped, - true, // notLaunched - false, // hidden - false, // suspended - null, null, null, - false, // blockUninstall - INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0, - PackageManager.INSTALL_REASON_UNKNOWN); + true /*stopped*/, + true /*notLaunched*/, + false /*hidden*/, + false /*suspended*/, + instantApp, + null /*lastDisableAppCaller*/, + null /*enabledComponents*/, + null /*disabledComponents*/, + false /*blockUninstall*/, + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, + 0, PackageManager.INSTALL_REASON_UNKNOWN); } } } @@ -1643,15 +1647,18 @@ final class Settings { // consider all applications to be installed. for (PackageSetting pkg : mPackages.values()) { pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT, - true, // installed - false, // stopped - false, // notLaunched - false, // hidden - false, // suspended - null, null, null, - false, // blockUninstall - INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0, - PackageManager.INSTALL_REASON_UNKNOWN); + true /*installed*/, + false /*stopped*/, + false /*notLaunched*/, + false /*hidden*/, + false /*suspended*/, + false /*instantApp*/, + null /*lastDisableAppCaller*/, + null /*enabledComponents*/, + null /*disabledComponents*/, + false /*blockUninstall*/, + INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, + 0, PackageManager.INSTALL_REASON_UNKNOWN); } return; } @@ -1718,6 +1725,8 @@ final class Settings { false); final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser, ATTR_BLOCK_UNINSTALL, false); + final boolean instantApp = XmlUtils.readBooleanAttribute(parser, + ATTR_INSTANT_APP, false); final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED, COMPONENT_ENABLED_STATE_DEFAULT); final String enabledCaller = parser.getAttributeValue(null, @@ -1754,8 +1763,9 @@ final class Settings { } ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched, - hidden, suspended, enabledCaller, enabledComponents, disabledComponents, - blockUninstall, verifState, linkGeneration, installReason); + hidden, suspended, instantApp, enabledCaller, enabledComponents, + disabledComponents, blockUninstall, verifState, linkGeneration, + installReason); } else if (tagName.equals("preferred-activities")) { readPreferredActivitiesLPw(parser, userId); } else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) { @@ -2025,6 +2035,9 @@ final class Settings { if (ustate.blockUninstall) { serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true"); } + if (ustate.instantApp) { + serializer.attribute(null, ATTR_INSTANT_APP, "true"); + } if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) { serializer.attribute(null, ATTR_ENABLED, Integer.toString(ustate.enabled)); @@ -2682,7 +2695,7 @@ final class Settings { sb.append(isDebug ? " 1 " : " 0 "); sb.append(dataPath); sb.append(" "); - sb.append(ai.seinfo); + sb.append(ai.seInfo); sb.append(" "); if (gids != null && gids.length > 0) { sb.append(gids[0]); @@ -4140,7 +4153,7 @@ final class Settings { volumeUuids[i] = ps.volumeUuid; names[i] = ps.name; appIds[i] = ps.appId; - seinfos[i] = ps.pkg.applicationInfo.seinfo; + seinfos[i] = ps.pkg.applicationInfo.seInfo; targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion; } } @@ -4429,7 +4442,7 @@ final class Settings { ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE", ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE", ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE", - ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL", + ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL", ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER", ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET, "RESIZEABLE_ACTIVITIES_EXPLICITLY_SET", ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION, "RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION", @@ -4502,6 +4515,7 @@ final class Settings { pw.print(ps.getSuspended(user.id) ? "SU" : "su"); pw.print(ps.getStopped(user.id) ? "S" : "s"); pw.print(ps.getNotLaunched(user.id) ? "l" : "L"); + pw.print(ps.getInstantApp(user.id) ? "IA" : "ia"); pw.print(","); pw.print(ps.getEnabled(user.id)); String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id); @@ -4755,6 +4769,8 @@ final class Settings { pw.print(ps.getNotLaunched(user.id)); pw.print(" enabled="); pw.println(ps.getEnabled(user.id)); + pw.print(" instant="); + pw.println(ps.getInstantApp(user.id)); String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id); if (lastDisabledAppCaller != null) { pw.print(prefix); pw.print(" lastDisabledCaller: "); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index dd44aa0a53cb..d47c141f2e4b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -7892,7 +7892,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Install the profile owner if not present. if (!mIPackageManager.isPackageAvailable(adminPkg, userHandle)) { mIPackageManager.installExistingPackageAsUser(adminPkg, userHandle, - PackageManager.INSTALL_REASON_POLICY); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY); } } catch (RemoteException e) { Slog.e(LOG_TAG, "Failed to make remote calls for createAndManageUser, " @@ -8211,7 +8211,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Install the app. mIPackageManager.installExistingPackageAsUser(packageName, userId, - PackageManager.INSTALL_REASON_POLICY); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY); } catch (RemoteException re) { // shouldn't happen @@ -8253,7 +8253,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (isSystemApp(mIPackageManager, packageName, parentUserId)) { numberOfAppsInstalled++; mIPackageManager.installExistingPackageAsUser(packageName, userId, - PackageManager.INSTALL_REASON_POLICY); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY); } else { Slog.d(LOG_TAG, "Not enabling " + packageName + " since is not a" + " system app"); diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java index 3fa72dc92a88..90c58d0279a7 100644 --- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java +++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java @@ -104,7 +104,7 @@ class PreloadAppsInstaller { } try { mPackageManager.installExistingPackageAsUser(packageName, userId, - PackageManager.INSTALL_REASON_UNKNOWN); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } finally { @@ -175,4 +175,4 @@ class PreloadAppsInstaller { } } } -}
\ No newline at end of file +} diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java index e2e18447a709..100338e7bfbf 100644 --- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java @@ -1053,7 +1053,7 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase { ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED; } if (mEphemeralPackages.contains(PackageWithUser.of(userId, packageName))) { - ret.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL; + ret.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT; } if (mSystemPackages.contains(packageName)) { ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index baf60c539105..325d99a90e67 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -388,6 +388,7 @@ public class PackageManagerSettingsTests { ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/, null /*installUser*/, false /*allowInstall*/, + false /*instantApp*/, null /*parentPkgName*/, null /*childPkgNames*/, UserManagerService.getInstance(), @@ -428,6 +429,7 @@ public class PackageManagerSettingsTests { 0 /*pkgPrivateFlags*/, UserHandle.SYSTEM /*installUser*/, true /*allowInstall*/, + false /*instantApp*/, null /*parentPkgName*/, null /*childPkgNames*/, UserManagerService.getInstance(), @@ -471,6 +473,7 @@ public class PackageManagerSettingsTests { 0 /*pkgPrivateFlags*/, null /*installUser*/, false /*allowInstall*/, + false /*instantApp*/, null /*parentPkgName*/, null /*childPkgNames*/, UserManagerService.getInstance(), @@ -514,6 +517,7 @@ public class PackageManagerSettingsTests { 0 /*pkgPrivateFlags*/, null /*installUser*/, false /*allowInstall*/, + false /*instantApp*/, null /*parentPkgName*/, null /*childPkgNames*/, UserManagerService.getInstance(), diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java index e5640c7e08c1..5591029d9a0a 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java @@ -380,7 +380,7 @@ public class PackageParserTest { assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs)); assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs)); assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs)); - assertEquals(a.seinfo, that.seinfo); + assertEquals(a.seInfo, that.seInfo); assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles)); assertEquals(a.dataDir, that.dataDir); assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir); diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java index 346dc4235e6c..a8c39c43cb49 100644 --- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java +++ b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java @@ -104,7 +104,7 @@ public class PreloadAppsInstallerTest { null, null); // Verify that we try to install the package in system user. verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM, - PackageManager.INSTALL_REASON_UNKNOWN); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); } assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed", "1", @@ -141,7 +141,7 @@ public class PreloadAppsInstallerTest { null, null); // Verify that we try to install the package in system user. verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM, - PackageManager.INSTALL_REASON_UNKNOWN); + 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN); } assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed", "1", |