diff --git a/api/current.txt b/api/current.txt
index c294d8ae4b974..85aa5df723c92 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1425,6 +1425,7 @@ package android {
field public static final int viewportWidth = 16843778; // 0x1010402
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
+ field public static final int visibleToEphemeral = 16844095; // 0x101053f
field public static final int vmSafeMode = 16843448; // 0x10102b8
field public static final int voiceIcon = 16843908; // 0x1010484
field public static final int voiceLanguage = 16843349; // 0x1010255
diff --git a/api/system-current.txt b/api/system-current.txt
index a3672b3145b17..41fd0d442542d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1536,6 +1536,7 @@ package android {
field public static final int viewportWidth = 16843778; // 0x1010402
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
+ field public static final int visibleToEphemeral = 16844095; // 0x101053f
field public static final int vmSafeMode = 16843448; // 0x10102b8
field public static final int voiceIcon = 16843908; // 0x1010484
field public static final int voiceLanguage = 16843349; // 0x1010255
diff --git a/api/test-current.txt b/api/test-current.txt
index 11f1c5c99c11c..2a347d717da4f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1425,6 +1425,7 @@ package android {
field public static final int viewportWidth = 16843778; // 0x1010402
field public static final int visibility = 16842972; // 0x10100dc
field public static final int visible = 16843156; // 0x1010194
+ field public static final int visibleToEphemeral = 16844095; // 0x101053f
field public static final int vmSafeMode = 16843448; // 0x10102b8
field public static final int voiceIcon = 16843908; // 0x1010484
field public static final int voiceLanguage = 16843349; // 0x1010255
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index f5a79c8c13eb3..2c97ec42591f9 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -282,6 +282,10 @@ public class IntentFilter implements Parcelable {
private int mVerifyState;
+ /** 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.
@@ -647,6 +651,24 @@ public class IntentFilter implements Parcelable {
if (verified) mVerifyState |= STATE_VERIFIED;
}
+ /** @hide */
+ public void setVisibleToEphemeral(boolean visibleToEmphemeral) {
+ mVisibleToEphemeral = visibleToEmphemeral;
+ }
+ /** @hide */
+ public boolean isVisibleToEphemeral() {
+ 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/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 5d90acc068573..44dff002fa01a 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -362,6 +362,12 @@ public class ActivityInfo extends ComponentInfo
*/
public static final int FLAG_ON_TOP_LAUNCHER = 0x80000;
+ /**
+ * Bit in {@link #flags} indicating if the activity is visible to ephemeral applications.
+ * @hide
+ */
+ public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+
/**
* @hide Bit in {@link #flags}: If set, this component will only be seen
* by the system user. Only works with broadcast receivers. Set from the
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index ecdd02aca0f41..4411572b1fb62 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -449,6 +449,20 @@ public abstract class PackageManager {
*/
public static final int MATCH_KNOWN_PACKAGES = MATCH_UNINSTALLED_PACKAGES | MATCH_ANY_USER;
+ /**
+ * Internal {@link PackageInfo} flag: include components that are part of an
+ * ephemeral app. By default, ephemeral components are not matched.
+ * @hide
+ */
+ public static final int MATCH_EPHEMERAL = 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;
+
/**
* Internal flag used to indicate that a system component has done their
* homework and verified that they correctly handle packages and components
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 9b2dd68d2676a..d7c3722a1d556 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3780,6 +3780,13 @@ public class PackageParser {
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
+ final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
+ final boolean visibleToEphemeral = isEphemeral
+ || sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToEphemeral, false);
+ if (visibleToEphemeral) {
+ a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+ }
+
sa.recycle();
if (receiver && (owner.applicationInfo.privateFlags
@@ -3806,9 +3813,12 @@ public class PackageParser {
if (parser.getName().equals("intent-filter")) {
ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, true, true, intent, outError)) {
+ if (!parseIntent(res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/,
+ intent, outError)) {
return null;
}
+ intent.setEphemeral(isEphemeral);
+ intent.setVisibleToEphemeral(visibleToEphemeral);
if (intent.countActions() == 0) {
Slog.w(TAG, "No actions in intent filter at "
+ mArchiveSourcePath + " "
@@ -3818,9 +3828,12 @@ public class PackageParser {
}
} else if (!receiver && parser.getName().equals("preferred")) {
ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, false, false, intent, outError)) {
+ if (!parseIntent(res, parser, false /*allowGlobs*/, false /*allowAutoVerify*/,
+ intent, outError)) {
return null;
}
+ intent.setEphemeral(isEphemeral);
+ intent.setVisibleToEphemeral(visibleToEphemeral);
if (intent.countActions() == 0) {
Slog.w(TAG, "No actions in preferred at "
+ mArchiveSourcePath + " "
@@ -4071,6 +4084,10 @@ public class PackageParser {
}
}
+ final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
+ final boolean visibleToEphemeral = isEphemeral
+ || ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0);
+
sa.recycle();
if (outError[0] != null) {
@@ -4088,7 +4105,8 @@ public class PackageParser {
if (parser.getName().equals("intent-filter")) {
ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, true, true, intent, outError)) {
+ if (!parseIntent(res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/,
+ intent, outError)) {
return null;
}
if (intent.countActions() == 0) {
@@ -4096,6 +4114,8 @@ public class PackageParser {
+ mArchiveSourcePath + " "
+ parser.getPositionDescription());
} else {
+ intent.setEphemeral(isEphemeral);
+ intent.setVisibleToEphemeral(visibleToEphemeral);
a.intents.add(intent);
}
} else if (parser.getName().equals("meta-data")) {
@@ -4233,6 +4253,13 @@ public class PackageParser {
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
+ final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
+ final boolean visibleToEphemeral = isEphemeral
+ || sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToEphemeral, false);
+ if (visibleToEphemeral) {
+ p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+ }
+
sa.recycle();
if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
@@ -4255,15 +4282,15 @@ public class PackageParser {
}
p.info.authority = cpname.intern();
- if (!parseProviderTags(res, parser, p, outError)) {
+ if (!parseProviderTags(res, parser, isEphemeral, visibleToEphemeral, p, outError)) {
return null;
}
return p;
}
- private boolean parseProviderTags(Resources res,
- XmlResourceParser parser, Provider outInfo, String[] outError)
+ private boolean parseProviderTags(Resources res, XmlResourceParser parser,
+ boolean isEphemeral, boolean visibleToEphemeral, Provider outInfo, String[] outError)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
@@ -4276,9 +4303,12 @@ public class PackageParser {
if (parser.getName().equals("intent-filter")) {
ProviderIntentInfo intent = new ProviderIntentInfo(outInfo);
- if (!parseIntent(res, parser, true, false, intent, outError)) {
+ if (!parseIntent(res, parser, true /*allowGlobs*/, false /*allowAutoVerify*/,
+ intent, outError)) {
return false;
}
+ intent.setEphemeral(isEphemeral);
+ intent.setVisibleToEphemeral(visibleToEphemeral);
outInfo.intents.add(intent);
} else if (parser.getName().equals("meta-data")) {
@@ -4526,6 +4556,13 @@ public class PackageParser {
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
+ final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
+ final boolean visibleToEphemeral = isEphemeral
+ || sa.getBoolean(R.styleable.AndroidManifestService_visibleToEphemeral, false);
+ if (visibleToEphemeral) {
+ s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
+ }
+
sa.recycle();
if ((owner.applicationInfo.privateFlags&ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
@@ -4549,9 +4586,12 @@ public class PackageParser {
if (parser.getName().equals("intent-filter")) {
ServiceIntentInfo intent = new ServiceIntentInfo(s);
- if (!parseIntent(res, parser, true, false, intent, outError)) {
+ if (!parseIntent(res, parser, true /*allowGlobs*/, false /*allowAutoVerify*/,
+ intent, outError)) {
return null;
}
+ intent.setEphemeral(isEphemeral);
+ intent.setVisibleToEphemeral(visibleToEphemeral);
s.intents.add(intent);
} else if (parser.getName().equals("meta-data")) {
@@ -4755,9 +4795,9 @@ public class PackageParser {
private static final String ANDROID_RESOURCES
= "http://schemas.android.com/apk/res/android";
- private boolean parseIntent(Resources res, XmlResourceParser parser,
- boolean allowGlobs, boolean allowAutoVerify, IntentInfo outInfo, String[] outError)
- throws XmlPullParserException, IOException {
+ private boolean parseIntent(Resources res, XmlResourceParser parser, boolean allowGlobs,
+ boolean allowAutoVerify, IntentInfo outInfo, String[] outError)
+ throws XmlPullParserException, IOException {
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestIntentFilter);
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
index 7e7b32f03fd19..8c21563198abb 100644
--- a/core/java/android/content/pm/ProviderInfo.java
+++ b/core/java/android/content/pm/ProviderInfo.java
@@ -75,6 +75,12 @@ public final class ProviderInfo extends ComponentInfo
* running in the same process. Higher goes first. */
public int initOrder = 0;
+ /**
+ * Bit in {@link #flags} indicating if the provider is visible to ephemeral applications.
+ * @hide
+ */
+ public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+
/**
* Bit in {@link #flags}: If set, a single instance of the provider will
* run for all users on the device. Set from the
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 6bd285a6c3942..f0766beb5d3f7 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -55,6 +55,12 @@ public class ServiceInfo extends ComponentInfo
*/
public static final int FLAG_EXTERNAL_SERVICE = 0x0004;
+ /**
+ * Bit in {@link #flags} indicating if the service is visible to ephemeral applications.
+ * @hide
+ */
+ public static final int FLAG_VISIBLE_TO_EPHEMERAL = 0x100000;
+
/**
* Bit in {@link #flags}: If set, a single instance of the service will
* run for all users on the device. Set from the
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 967c4ad340ece..c91f0a51d5bda 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1209,6 +1209,10 @@
-->
+
+
+
@@ -1731,6 +1735,7 @@
+
+
-
+
+