Merge "Per user setting for instant app"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 7015381..51b2d3d 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -553,8 +553,12 @@
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 333e412..1652299 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1687,7 +1687,7 @@
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 e6cae69..56609eb 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -284,8 +284,6 @@
/** 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 @@
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 1fa4181..9737b11 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -498,11 +498,12 @@
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 @@
*
* {@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 @@
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 @@
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 @@
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 @@
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 @@
} else {
dataDir = credentialProtectedDataDir;
}
- // TODO: modify per-user ephemerality
}
/**
@@ -1415,7 +1433,7 @@
* @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 9d36a73..ffb777d 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -553,7 +553,8 @@
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 4de967c..278a6d0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1096,9 +1096,11 @@
@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 308153d..5733982 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -452,17 +452,17 @@
/**
* 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 @@
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 @@
*
* @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 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 7a9aaaf..98e71a0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -720,6 +720,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
// 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 @@
+ 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 @@
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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
} 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 @@
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 e19aa99..24f1164 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -43,6 +43,7 @@
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 @@
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 @@
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 0000000..871f672
--- /dev/null
+++ b/core/java/android/content/pm/SELinuxUtil.java
@@ -0,0 +1,43 @@
+/*
+ * 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 */
+ private static final String COMPLETE_TAG = "complete";
+ private static final String COMPLETE_STR = ":" + COMPLETE_TAG;
+
+ /** @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 2dfba28..b554e2d 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4128,20 +4128,20 @@
}
/**
- * 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);
}
/**
@@ -6988,17 +6988,17 @@
}
/**
- * 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);
}
/**
@@ -10136,16 +10136,16 @@
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 eec3cb0..e088717 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -534,7 +534,7 @@
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 4c11197..0fc9a4d 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 @@
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 4df199c..8cfec7a 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 @@
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 edcb9b5..a3a8553 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 @@
}
}
- 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 @@
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 @@
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 14abb53..40499c9 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -351,7 +351,7 @@
}
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 @@
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 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 @@
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 @@
}
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 @@
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 a73eb18..d9123f4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -293,6 +293,7 @@
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;
@@ -3776,6 +3777,11 @@
app.requiredAbi = requiredAbi;
app.instructionSet = instructionSet;
+ // the per-user SELinux context must be set
+ if (TextUtils.isEmpty(app.info.seInfoUser)) {
+ throw new IllegalStateException("SELinux tag not defined");
+ }
+ final String seInfo = app.info.seInfo + 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 +3793,12 @@
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 +3814,7 @@
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 +18780,7 @@
}
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 +18789,7 @@
}
} 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 95734a4..2f84486 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1196,7 +1196,7 @@
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 93c14b9..376a864 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 @@
// 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 3c55422..d99a1b6 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 @@
}
}
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 42934a4..23925ad 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 @@
propagateInstantAppPermissionsIfNeeded(pkg.packageName, userId);
// Track instant apps
- if (pkg.applicationInfo.isInstantApp()) {
+ if (ps.getInstantApp(userId)) {
addInstantAppLPw(userId, ps.appId);
}
@@ -257,7 +257,7 @@
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 @@
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 efd3132..eb42f80 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 @@
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 067a136..463cfac 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 @@
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 0d63f72..5aecbd8 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_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.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 @@
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 = "_";
@@ -1779,28 +1783,32 @@
// 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;
- }
+ 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);
- }
+ }
+ 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
@@ -1887,16 +1895,14 @@
}
}
- 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);
}
}
@@ -3335,14 +3341,14 @@
&& 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)) {
@@ -3953,17 +3959,17 @@
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);
}
@@ -4692,7 +4698,8 @@
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);
}
@@ -5741,8 +5748,7 @@
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();
@@ -5814,8 +5820,7 @@
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;
@@ -5986,8 +5991,7 @@
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;
}
@@ -6006,16 +6010,17 @@
}
/**
- * 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;
@@ -6024,7 +6029,7 @@
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 */,
@@ -6046,14 +6051,14 @@
// 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();
@@ -6080,7 +6085,7 @@
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.
@@ -6120,13 +6125,13 @@
// 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.
@@ -6140,7 +6145,7 @@
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
@@ -6178,7 +6183,7 @@
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
}
- return filterForEphemeral(result, ephemeralPkgName);
+ return filterForEphemeral(result, instantAppPkgName);
}
private static class CrossProfileDomainInfo {
@@ -7142,9 +7147,9 @@
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;
@@ -7647,7 +7652,7 @@
* @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
@@ -7687,7 +7692,7 @@
* @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;
@@ -7923,6 +7928,11 @@
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);
@@ -8860,7 +8870,7 @@
}
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
@@ -8899,7 +8909,8 @@
}
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,
@@ -8965,7 +8976,7 @@
}
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)
@@ -9103,16 +9114,16 @@
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);
@@ -9179,9 +9190,8 @@
}
if (mFoundPolicyFile) {
- SELinuxMMAC.assignSeinfoValue(pkg);
+ SELinuxMMAC.assignSeInfoValue(pkg);
}
-
pkg.applicationInfo.uid = pkgSetting.appId;
pkg.mExtras = pkgSetting;
@@ -9416,11 +9426,11 @@
}
}
} 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);
}
}
@@ -9535,10 +9545,10 @@
"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
@@ -9781,7 +9791,6 @@
mPlatformPackage = pkg;
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
-
if (!mResolverReplaced) {
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
@@ -10070,10 +10079,10 @@
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);
@@ -10115,10 +10124,10 @@
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;
}
@@ -11740,13 +11749,10 @@
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,
@@ -11755,8 +11761,7 @@
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,
@@ -11767,9 +11772,6 @@
}
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);
@@ -11784,8 +11786,7 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly,
- vislbleToEphemeral, isEphemeral, listCut, userId);
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
/**
@@ -12197,11 +12198,24 @@
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) {
@@ -12270,10 +12284,9 @@
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,
@@ -12282,8 +12295,7 @@
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,
@@ -12294,9 +12306,6 @@
}
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);
@@ -12311,8 +12320,7 @@
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) {
@@ -12487,10 +12495,9 @@
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,
@@ -12500,8 +12507,7 @@
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,
@@ -12513,9 +12519,6 @@
}
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);
@@ -12530,8 +12533,7 @@
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) {
@@ -13072,7 +13074,7 @@
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);
}
}
@@ -13287,7 +13289,8 @@
* @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;
@@ -13302,6 +13305,10 @@
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) {
@@ -13316,7 +13323,11 @@
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) {
@@ -13338,6 +13349,29 @@
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)) {
@@ -13696,7 +13730,7 @@
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");
}
@@ -14488,7 +14522,7 @@
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) {
@@ -14572,7 +14606,7 @@
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 {
@@ -14906,7 +14940,7 @@
}
protected boolean isEphemeral() {
- return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
+ return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
}
UserHandle getUser() {
@@ -14986,7 +15020,7 @@
}
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;
@@ -15813,7 +15847,7 @@
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;
@@ -15837,17 +15871,17 @@
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,
@@ -16049,6 +16083,10 @@
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) {
@@ -16520,7 +16558,8 @@
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;
@@ -16531,6 +16570,12 @@
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);
@@ -16538,10 +16583,10 @@
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;
}
@@ -16550,7 +16595,7 @@
| 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);
@@ -16569,7 +16614,7 @@
// // 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;
@@ -16812,10 +16857,10 @@
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;
}
}
@@ -17062,14 +17107,6 @@
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;
}
@@ -17092,9 +17129,6 @@
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
@@ -17496,7 +17530,7 @@
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) {
@@ -17646,7 +17680,7 @@
}
}
- removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
+ removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
final PackageParser.Package resolvedPkg;
@@ -18205,11 +18239,18 @@
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);
}
@@ -21691,12 +21732,12 @@
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
@@ -21704,7 +21745,7 @@
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!");
@@ -22006,7 +22047,7 @@
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");
@@ -22815,8 +22856,8 @@
@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 1203e4d..a7349fc 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.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 @@
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 @@
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 @@
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 0e11b0c..601377d6 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 @@
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 @@
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 7e7de21..188e66f 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 @@
// 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 @@
*
* @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 @@
* @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 6156802..a8a5ff0 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 @@
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 @@
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 @@
|| 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 @@
// 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 @@
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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 2b2bb48..ba8f7e9 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7863,7 +7863,7 @@
// 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, "
@@ -8182,7 +8182,7 @@
// Install the app.
mIPackageManager.installExistingPackageAsUser(packageName, userId,
- PackageManager.INSTALL_REASON_POLICY);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
} catch (RemoteException re) {
// shouldn't happen
@@ -8224,7 +8224,7 @@
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 3fa72dc..90c58d0 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 @@
}
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 @@
}
}
}
-}
\ 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 e2e1844..100338e 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 @@
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 baf60c5..325d99a 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 @@
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
null /*installUser*/,
false /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -428,6 +429,7 @@
0 /*pkgPrivateFlags*/,
UserHandle.SYSTEM /*installUser*/,
true /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -471,6 +473,7 @@
0 /*pkgPrivateFlags*/,
null /*installUser*/,
false /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -514,6 +517,7 @@
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 e5640c7..5591029 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 @@
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 346dc42..a8c39c4 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 @@
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 @@
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",