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 @@ + + - + +